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