in java/java.hints/src/org/netbeans/modules/java/hints/ArithmeticUtilities.java [525:876]
public Object visitBinary(BinaryTree node, Void p) {
Object left = scan(node.getLeftOperand(), p);
Object right = scan(node.getRightOperand(), p);
// JSL 5.6.2, binary numeric promotion + JLS 5.1.2, widening primitive conversion for char values.
// other value types are handled by the Number class in JDK. Chars may be promoted further to float / double.
if (left instanceof Character && !(right instanceof String)) {
left = Integer.valueOf(((Character)left).charValue());
}
if (right instanceof Character && !(left instanceof String)) {
right = Integer.valueOf(((Character)right).charValue());
}
if (left != null && right != null) {
Object result = null;
switch (node.getKind()) {
case EQUAL_TO:
if (left instanceof Number && right instanceof Number) {
result = numericBinaryOp(OP_EQUAL, left, right);
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() == rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() == rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() == rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() == rn.intValue();
} else {
return null;
}
} else if (left instanceof Boolean && right instanceof Boolean) {
return left.equals(right);
} else if (left == NULL || right == NULL) {
// cannot accept primitives, boxing conversion does not apply
TypeMirror m = info.getTrees().getTypeMirror(
new TreePath(getCurrentPath(),
left == NULL ? node.getRightOperand() :
node.getLeftOperand()
));
if (Utilities.isValidType(m) && !PRIMITIVE_KINDS.contains(m.getKind())) {
result = left == right;
}
}
break;
case NOT_EQUAL_TO:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() != rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() != rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() != rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() != rn.intValue();
} else {
return null;
}
} else if (left instanceof Boolean && right instanceof Boolean) {
return left.equals(right);
} else if (enhanceProcessing && (left == NULL || right == NULL)) {
// cannot accept primitives, boxing conversion does not apply
TypeMirror m = info.getTrees().getTypeMirror(new TreePath(getCurrentPath(),
left == NULL ? node.getRightOperand() : node.getLeftOperand()));
if (Utilities.isValidType(m) && !PRIMITIVE_KINDS.contains(m.getKind())) {
result = left != right;
}
}
break;
case LESS_THAN:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() < rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() < rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() < rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() < rn.intValue();
} else {
return null;
}
}
break;
case LESS_THAN_EQUAL:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() <= rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() <= rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() <= rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() <= rn.intValue();
} else {
return null;
}
}
break;
case GREATER_THAN:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() > rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() > rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() > rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() > rn.intValue();
} else {
return null;
}
}
break;
case GREATER_THAN_EQUAL:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() >= rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() >= rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() >= rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() >= rn.intValue();
} else {
return null;
}
}
break;
case MULTIPLY:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() * rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() * rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() * rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() * rn.intValue();
} else {
return null;
}
}
break;
case DIVIDE:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() / rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() / rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() / rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() / rn.intValue();
} else {
return null;
}
}
boolean a = true;
boolean b = false;
boolean c = a & b;
break;
case REMAINDER:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() % rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() % rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() % rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() % rn.intValue();
} else {
return null;
}
}
break;
case MINUS:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() - rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() - rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() - rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() - rn.intValue();
} else {
return null;
}
}
break;
case LEFT_SHIFT:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Long || right instanceof Long) {
result = ln.longValue() << rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() << rn.intValue();
} else {
return null;
}
}
break;
case RIGHT_SHIFT:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Long || right instanceof Long) {
result = ln.longValue() >> rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() >> rn.intValue();
} else {
return null;
}
}
break;
case UNSIGNED_RIGHT_SHIFT:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Long || right instanceof Long) {
result = ln.longValue() >>> rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() >>> rn.intValue();
} else {
return null;
}
}
break;
// PLUS is also supported for String operands. `null' value is represented by String containing "null",
// so it will produce the correct concatenation result.
case PLUS:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Double || right instanceof Double) {
result = ln.doubleValue() + rn.doubleValue();
} else if (left instanceof Float || right instanceof Float) {
result = ln.floatValue() + rn.floatValue();
} else if (left instanceof Long || right instanceof Long) {
result = ln.longValue() + rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() + rn.intValue();
} else {
return null;
}
} else if (left instanceof String) {
if (right != NOT_NULL) {
result = (String)left + right;
}
} else if (right instanceof String) {
if (left != NOT_NULL) {
result = left + (String)right;
}
}
break;
// AND, OR apply as well to booleans
case CONDITIONAL_AND:
if (left instanceof Boolean && right instanceof Boolean) {
result = ((Boolean)left) && ((Boolean)right);
}
break;
case CONDITIONAL_OR:
if (left instanceof Boolean && right instanceof Boolean) {
result = ((Boolean)left) || ((Boolean)right);
}
break;
case XOR:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Long || right instanceof Long) {
result = ln.longValue() ^ rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() ^ rn.intValue();
} else {
return null;
}
} else if (left instanceof Boolean && right instanceof Boolean) {
result = ((Boolean)left) ^ ((Boolean)right);
}
break;
case AND:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Long || right instanceof Long) {
result = ln.longValue() & rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() & rn.intValue();
} else {
return null;
}
} else if (left instanceof Boolean && right instanceof Boolean) {
result = ((Boolean)left) & ((Boolean)right);
}
break;
case OR:
if (left instanceof Number && right instanceof Number) {
Number ln = (Number)left;
Number rn = (Number)right;
if (left instanceof Long || right instanceof Long) {
result = ln.longValue() | rn.longValue();
} else if (integerLike(ln) || integerLike(rn)) {
result = ln.intValue() | rn.intValue();
} else {
return null;
}
} else if (left instanceof Boolean && right instanceof Boolean) {
result = ((Boolean)left) | ((Boolean)right);
}
break;
}
return result;
}
return null;
}