public void visitBinaryMath()

in modules/lang-painless/src/main/java/org/elasticsearch/painless/phase/DefaultConstantFoldingOptimizationPhase.java [156:398]


    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) {
            ExpressionNode irLeftConstantNode = irBinaryMathNode.getLeftNode();
            ExpressionNode irRightConstantNode = irBinaryMathNode.getRightNode();
            Object leftConstantValue = irLeftConstantNode.getDecorationValue(IRDConstant.class);
            Object rightConstantValue = irRightConstantNode.getDecorationValue(IRDConstant.class);
            Operation operation = irBinaryMathNode.getDecorationValue(IRDOperation.class);
            Class<?> type = irBinaryMathNode.getDecorationValue(IRDExpressionType.class);

            if (operation == Operation.MUL) {
                if (type == int.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue * (int) rightConstantValue));
                } else if (type == long.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue * (long) rightConstantValue));
                } else if (type == float.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((float) leftConstantValue * (float) rightConstantValue));
                } else if (type == double.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((double) leftConstantValue * (double) rightConstantValue));
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            binaryError(
                                PainlessLookupUtility.typeToCanonicalTypeName(type),
                                operation.symbol,
                                irLeftConstantNode.getDecorationString(IRDConstant.class),
                                irRightConstantNode.getDecorationString(IRDConstant.class)
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.DIV) {
                try {
                    if (type == int.class) {
                        irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue / (int) rightConstantValue));
                    } else if (type == long.class) {
                        irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue / (long) rightConstantValue));
                    } else if (type == float.class) {
                        irLeftConstantNode.attachDecoration(new IRDConstant((float) leftConstantValue / (float) rightConstantValue));
                    } else if (type == double.class) {
                        irLeftConstantNode.attachDecoration(new IRDConstant((double) leftConstantValue / (double) rightConstantValue));
                    } else {
                        throw irBinaryMathNode.getLocation()
                            .createError(
                                binaryError(
                                    PainlessLookupUtility.typeToCanonicalTypeName(type),
                                    operation.symbol,
                                    irLeftConstantNode.getDecorationString(IRDConstant.class),
                                    irRightConstantNode.getDecorationString(IRDConstant.class)
                                )
                            );
                    }
                } catch (ArithmeticException ae) {
                    throw irBinaryMathNode.getLocation().createError(ae);
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.REM) {
                try {
                    if (type == int.class) {
                        irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue % (int) rightConstantValue));
                    } else if (type == long.class) {
                        irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue % (long) rightConstantValue));
                    } else if (type == float.class) {
                        irLeftConstantNode.attachDecoration(new IRDConstant((float) leftConstantValue % (float) rightConstantValue));
                    } else if (type == double.class) {
                        irLeftConstantNode.attachDecoration(new IRDConstant((double) leftConstantValue % (double) rightConstantValue));
                    } else {
                        throw irBinaryMathNode.getLocation()
                            .createError(
                                binaryError(
                                    PainlessLookupUtility.typeToCanonicalTypeName(type),
                                    operation.symbol,
                                    irLeftConstantNode.getDecorationString(IRDConstant.class),
                                    irRightConstantNode.getDecorationString(IRDConstant.class)
                                )
                            );
                    }
                } catch (ArithmeticException ae) {
                    throw irBinaryMathNode.getLocation().createError(ae);
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.ADD) {
                if (type == int.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue + (int) rightConstantValue));
                } else if (type == long.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue + (long) rightConstantValue));
                } else if (type == float.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((float) leftConstantValue + (float) rightConstantValue));
                } else if (type == double.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((double) leftConstantValue + (double) rightConstantValue));
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            binaryError(
                                PainlessLookupUtility.typeToCanonicalTypeName(type),
                                operation.symbol,
                                irLeftConstantNode.getDecorationString(IRDConstant.class),
                                irRightConstantNode.getDecorationString(IRDConstant.class)
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.SUB) {
                if (type == int.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue - (int) rightConstantValue));
                } else if (type == long.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue - (long) rightConstantValue));
                } else if (type == float.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((float) leftConstantValue - (float) rightConstantValue));
                } else if (type == double.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((double) leftConstantValue - (double) rightConstantValue));
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            binaryError(
                                PainlessLookupUtility.typeToCanonicalTypeName(type),
                                operation.symbol,
                                irLeftConstantNode.getDecorationString(IRDConstant.class),
                                irRightConstantNode.getDecorationString(IRDConstant.class)
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.LSH) {
                if (type == int.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue << (int) rightConstantValue));
                } else if (type == long.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue << (int) rightConstantValue));
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            binaryError(
                                PainlessLookupUtility.typeToCanonicalTypeName(type),
                                operation.symbol,
                                irLeftConstantNode.getDecorationString(IRDConstant.class),
                                irRightConstantNode.getDecorationString(IRDConstant.class)
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.RSH) {
                if (type == int.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue >> (int) rightConstantValue));
                } else if (type == long.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue >> (int) rightConstantValue));
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            binaryError(
                                PainlessLookupUtility.typeToCanonicalTypeName(type),
                                operation.symbol,
                                irLeftConstantNode.getDecorationString(IRDConstant.class),
                                irRightConstantNode.getDecorationString(IRDConstant.class)
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.USH) {
                if (type == int.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue >>> (int) rightConstantValue));
                } else if (type == long.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue >>> (int) rightConstantValue));
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            binaryError(
                                PainlessLookupUtility.typeToCanonicalTypeName(type),
                                operation.symbol,
                                irLeftConstantNode.getDecorationString(IRDConstant.class),
                                irRightConstantNode.getDecorationString(IRDConstant.class)
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.BWAND) {
                if (type == int.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue & (int) rightConstantValue));
                } else if (type == long.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue & (long) rightConstantValue));
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            binaryError(
                                PainlessLookupUtility.typeToCanonicalTypeName(type),
                                operation.symbol,
                                irLeftConstantNode.getDecorationString(IRDConstant.class),
                                irRightConstantNode.getDecorationString(IRDConstant.class)
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.XOR) {
                if (type == boolean.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((boolean) leftConstantValue ^ (boolean) rightConstantValue));
                } else if (type == int.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue ^ (int) rightConstantValue));
                } else if (type == long.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue ^ (long) rightConstantValue));
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            binaryError(
                                PainlessLookupUtility.typeToCanonicalTypeName(type),
                                operation.symbol,
                                irLeftConstantNode.getDecorationString(IRDConstant.class),
                                irRightConstantNode.getDecorationString(IRDConstant.class)
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.BWOR) {
                if (type == int.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((int) leftConstantValue | (int) rightConstantValue));
                } else if (type == long.class) {
                    irLeftConstantNode.attachDecoration(new IRDConstant((long) leftConstantValue | (long) rightConstantValue));
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            binaryError(
                                PainlessLookupUtility.typeToCanonicalTypeName(type),
                                operation.symbol,
                                irLeftConstantNode.getDecorationString(IRDConstant.class),
                                irRightConstantNode.getDecorationString(IRDConstant.class)
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            }
        }
    }