All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.pmd.lang.java.ast.BinaryOp Maven / Gradle / Ivy

There is a newer version: 7.7.0
Show newest version
/**
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 */

package net.sourceforge.pmd.lang.java.ast;

import java.util.Comparator;
import java.util.EnumSet;
import java.util.Set;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils;
import net.sourceforge.pmd.util.CollectionUtil;

/**
 * Represents the operator of an {@linkplain ASTInfixExpression infix expression}.
 * Constants are roughly ordered by precedence, except some of them have the same
 * precedence.
 *
 * 

All of those operators are left-associative. * * @see UnaryOp * @see AssignmentOp */ public enum BinaryOp implements InternalInterfaces.OperatorLike { // shortcut boolean ops /** Conditional (shortcut) OR {@code "||"} operator. */ CONDITIONAL_OR("||"), /** Conditional (shortcut) AND {@code "&&"} operator. */ CONDITIONAL_AND("&&"), // non-shortcut (also bitwise) /** OR {@code "|"} operator. Either logical or bitwise depending on the type of the operands. */ OR("|"), /** XOR {@code "^"} operator. Either logical or bitwise depending on the type of the operands. */ XOR("^"), /** AND {@code "&"} operator. Either logical or bitwise depending on the type of the operands. */ AND("&"), // equality /** Equals {@code "=="} operator. */ EQ("=="), /** Not-equals {@code "!="} operator. */ NE("!="), // relational /** Lower-or-equal {@code "<="} operator. */ LE("<="), /** Greater-or-equal {@code ">="} operator. */ GE(">="), /** Greater-than {@code ">"} operator. */ GT(">"), /** Lower-than {@code "<"} operator. */ LT("<"), /** Type test {@code "instanceof"} operator. */ INSTANCEOF("instanceof"), // shift /** Left shift {@code "<<"} operator. */ LEFT_SHIFT("<<"), /** Right shift {@code ">>"} operator. */ RIGHT_SHIFT(">>"), /** Unsigned right shift {@code ">>>"} operator. */ UNSIGNED_RIGHT_SHIFT(">>>"), // additive /** Addition {@code "+"} operator, or string concatenation. */ ADD("+"), /** Subtraction {@code "-"} operator. */ SUB("-"), // multiplicative /** Multiplication {@code "*"} operator. */ MUL("*"), /** Division {@code "/"} operator. */ DIV("/"), /** Modulo {@code "%"} operator. */ MOD("%"); /** Set of {@code &&} and {@code ||}. Use with {@link JavaAstUtils#isInfixExprWithOperator(JavaNode, Set)}. */ public static final Set CONDITIONAL_OPS = CollectionUtil.immutableEnumSet(CONDITIONAL_AND, CONDITIONAL_OR); /** Set of {@code <}, {@code <=}, {@code >=} and {@code >}. Use with {@link JavaAstUtils#isInfixExprWithOperator(JavaNode, Set)}. */ public static final Set COMPARISON_OPS = CollectionUtil.immutableEnumSet(LE, GE, GT, LT); /** Set of {@code ==} and {@code !=}. Use with {@link JavaAstUtils#isInfixExprWithOperator(JavaNode, Set)}. */ public static final Set EQUALITY_OPS = CollectionUtil.immutableEnumSet(EQ, NE); /** Set of {@code <<}, {@code >>} and {@code >>>}. Use with {@link JavaAstUtils#isInfixExprWithOperator(JavaNode, Set)}. */ public static final Set SHIFT_OPS = CollectionUtil.immutableEnumSet(LEFT_SHIFT, RIGHT_SHIFT, UNSIGNED_RIGHT_SHIFT); private final String code; BinaryOp(String code) { this.code = code; } @Override public String getToken() { return code; } @Override public String toString() { return this.code; } /** * Compare the precedence of this operator with that of the other, * as if with a {@link Comparator}. Returns a positive integer if * this operator has a higher precedence as the argument, zero if * they have the same precedence, etc. * * @throws NullPointerException If the argument is null */ public int comparePrecedence(@NonNull BinaryOp other) { // arguments are flipped because precedence class decreases return Integer.compare(other.precedenceClass(), this.precedenceClass()); } /** * Returns true if this operator has the same relative precedence * as the argument. For example, {@link #ADD} and {@link #SUB} have * the same precedence. * * @throws NullPointerException If the argument is null */ public boolean hasSamePrecedenceAs(@NonNull BinaryOp other) { return comparePrecedence(other) == 0; } /** * Returns the ops with strictly greater precedence than the given op. * This may return an empty set. */ public static Set opsWithGreaterPrecedence(BinaryOp op) { Set range = EnumSet.range(op, MOD); range.remove(op); return range; } private int precedenceClass() { switch (this) { case CONDITIONAL_OR: return 9; case CONDITIONAL_AND: return 8; case OR: return 7; case XOR: return 6; case AND: return 5; case EQ: case NE: return 4; case LE: case GE: case GT: case LT: case INSTANCEOF: return 3; case LEFT_SHIFT: case RIGHT_SHIFT: case UNSIGNED_RIGHT_SHIFT: return 2; case ADD: case SUB: return 1; case MUL: case DIV: case MOD: return 0; default: return -1; } } /** * Complement, for boolean operators. Eg for {@code ==}, return {@code !=}, * for {@code <=}, returns {@code >}. Returns null if this is another kind * of operator. */ public @Nullable BinaryOp getComplement() { switch (this) { case CONDITIONAL_OR: return CONDITIONAL_AND; case CONDITIONAL_AND: return CONDITIONAL_OR; case OR: return AND; case AND: return OR; case EQ: return NE; case NE: return EQ; case LE: return GT; case GE: return LT; case GT: return LE; case LT: return GE; default: return null; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy