/* * Copyright 2013 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.errorprone.matchers; import com.google.errorprone.VisitorState; import com.sun.source.tree.CompoundAssignmentTree; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.Tree.Kind; import java.util.HashSet; import java.util.Set; /** * Matcher for a compound-assignment operator expression. */ public class CompoundAssignment implements Matcher<CompoundAssignmentTree> { private static final Set<Kind> COMPOUND_ASSIGNMENT_OPERATORS = new HashSet<>(11); static { COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.AND_ASSIGNMENT); COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.DIVIDE_ASSIGNMENT); COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.LEFT_SHIFT_ASSIGNMENT); COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.MINUS_ASSIGNMENT); COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.MULTIPLY_ASSIGNMENT); COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.OR_ASSIGNMENT); COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.PLUS_ASSIGNMENT); COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.REMAINDER_ASSIGNMENT); COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.RIGHT_SHIFT_ASSIGNMENT); COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT); COMPOUND_ASSIGNMENT_OPERATORS.add(Kind.XOR_ASSIGNMENT); } private final Set<Kind> operators; private final Matcher<ExpressionTree> receiverMatcher; private final Matcher<ExpressionTree> expressionMatcher; /** * Creates a new compound-assignment operator matcher, which matches a compound assignment * expression with one of a set of operators and whose receiver and expression match the given * matchers. * * @param operators The set of matching compound-assignment operators. These are drawn from the * {@link Kind} enum values which link to {@link CompoundAssignmentTree} in their javadoc. * @param receiverMatcher The matcher which must match the receiver which will be assigned to. * @param expressionMatcher The matcher which must match the right-hand expression to the compound * assignment. */ public CompoundAssignment(Set<Kind> operators, Matcher<ExpressionTree> receiverMatcher, Matcher<ExpressionTree> expressionMatcher) { this.operators = validateOperators(operators); if (receiverMatcher == null) { throw new NullPointerException("CompoundAssignment receiver matcher is null"); } if (expressionMatcher == null) { throw new NullPointerException("CompoundAssignment expression matcher is null"); } this.receiverMatcher = receiverMatcher; this.expressionMatcher = expressionMatcher; } @Override public boolean matches(CompoundAssignmentTree compoundAssignmentTree, VisitorState state) { if (!operators.contains(compoundAssignmentTree.getKind())) { return false; } return receiverMatcher.matches(compoundAssignmentTree.getVariable(), state) && expressionMatcher.matches(compoundAssignmentTree.getExpression(), state); } /** * Returns the provided set of operators if they are all compound-assignment operators. Otherwise, * throws an IllegalArgumentException. */ private static Set<Kind> validateOperators(Set<Kind> kinds) { for (Kind kind : kinds) { if (!COMPOUND_ASSIGNMENT_OPERATORS.contains(kind)) { throw new IllegalArgumentException(kind.name() + " is not a compound-assignment operator."); } } return kinds; } }