Matches an assignment operator AST node if both of the given matchers match.

@param variableMatcher The matcher to apply to the variable.
@param expressionMatcher The matcher to apply to the expression.
425070
public static Matcher<AssignmentTree> assignment(
      final Matcher<ExpressionTree> variableMatcher,
      final Matcher<? super ExpressionTree> expressionMatcher) {
    return new Matcher<AssignmentTree>() {
      @Override
      public boolean matches(AssignmentTree t, VisitorState state) {
        return variableMatcher.matches(t.getVariable(), state)
            && expressionMatcher.matches(t.getExpression(), state);
      }
    };
  }
3727
private static void buildMatchVariables(
      TypeSpec.Builder type, Map<String, Set<String>> territoryData, LanguageMatchingData data) {
    
    Map<String, Set<String>> territories = flatten(territoryData);
    
    CodeBlock.Builder code = CodeBlock.builder();
    code.add("new $T<$T, $T<$T>>() {{\n", HASHMAP, STRING, SET, STRING);
    for (Map.Entry<String, Set<String>> entry : territories.entrySet()) {
      code.add("  put($S, new $T<>(", entry.getKey(), HASHSET);
      List<String> list = new ArrayList<>(entry.getValue());
      Collections.sort(list);
      addStringList(code, list, "    ");
      code.add("));\n");
    }
    code.add("\n}}");
    
    TypeName typeName = ParameterizedTypeName.get(MAP, STRING, SET_STRING);
    type.addField(FieldSpec.builder(typeName, "TERRITORIES", PROTECTED, STATIC, FINAL)
        .initializer(code.build())
        .build());

    // Generate mapping for each variable and its inverse.
    Map<String, Set<String>> variables = new LinkedHashMap<>();
    
    for (Pair<String, String> pair : data.matchVariables) {
      String variable = pair._1;
      
      Set<String> countries = new HashSet<>();
      for (String regionId : pair._2.split("\\+")) {
        Set<String> children = territories.get(regionId);
        if (children != null) {
          countries.addAll(children);
        } else {
          countries.add(regionId);
        }
      }

      variables.put(variable, countries);
    }

    // Build the final variable tables.
    code = CodeBlock.builder();
    code.add("new $T<$T, $T<$T>>() {{\n", HASHMAP, STRING, SET, STRING);
    for (Map.Entry<String, Set<String>> entry : variables.entrySet()) {
      code.add("  put($S, new $T<>(", entry.getKey(), HASHSET);
      List<String> list = new ArrayList<>(entry.getValue());
      Collections.sort(list);
      addStringList(code, list, "    ");
      code.add("));\n");
    }
    code.add("\n}}");
    
    type.addField(FieldSpec.builder(typeName, "VARIABLES", PROTECTED, STATIC, FINAL)
        .initializer(code.build())
        .build());
  }
723158
public static Matcher<ExpressionTree> isVariable() {
    return new Matcher<ExpressionTree>() {
      @Override
      public boolean matches(ExpressionTree expressionTree, VisitorState state) {
        Symbol symbol = ASTHelpers.getSymbol(expressionTree);
        if (symbol == null) {
          return false;
        }
        return symbol.getKind() == ElementKind.LOCAL_VARIABLE
            || symbol.getKind() == ElementKind.PARAMETER;
      }
    };
  }
27451
public Configuration withMatcher(String matcherName, Matcher<?> matcher) {
        return new Configuration(tolerance, options, ignorePlaceholder, matchers.with(matcherName, matcher), pathsToBeIgnored, differenceListener);
    }
1063863
public static Matcher<VariableTree> variableType(final Matcher<Tree> treeMatcher) {
    return new Matcher<VariableTree>() {
      @Override
      public boolean matches(VariableTree variableTree, VisitorState state) {
        return treeMatcher.matches(variableTree.getType(), state);
      }
    };
  }
455055
static Matcher inlineMatchAnyPrecedingOr(Matcher matcher) {
    if (matcher instanceof ZeroOrMoreMatcher) {
      ZeroOrMoreMatcher zm = matcher.as();
      if (zm.repeated() instanceof AnyMatcher && zm.next() instanceof OrMatcher) {
        List<Matcher> matchers = zm.next().<OrMatcher>as().matchers();
        List<Matcher> ms = new ArrayList<>();
        for (Matcher m : matchers) {
          ms.add(new ZeroOrMoreMatcher(AnyMatcher.INSTANCE, m));
        }
        return OrMatcher.create(ms);
      }
    }
    return matcher;
  }
482011
private static boolean valueConstantsMatch(AbstractExpression e1, AbstractExpression e2) {
        return (e1 instanceof ParameterValueExpression && e2 instanceof ConstantValueExpression ||
                e1 instanceof ConstantValueExpression && e2 instanceof ParameterValueExpression) &&
                equalsAsCVE(e1, e2);
    }
204097
public TregexMatcher matcher(Tree t) {
    return matcher(t, t, new IdentityHashMap<Tree, Tree>(),
                   new HashMap<String, Tree>(), new VariableStrings());
  }
916618
public static Matcher<ExpressionTree> methodInvocation(
      final Matcher<ExpressionTree> methodSelectMatcher) {
    return new Matcher<ExpressionTree>() {
      @Override
      public boolean matches(ExpressionTree expressionTree, VisitorState state) {
        if (!(expressionTree instanceof MethodInvocationTree)) {
          return false;
        }
        MethodInvocationTree tree = (MethodInvocationTree) expressionTree;
        return methodSelectMatcher.matches(tree.getMethodSelect(), state);
      }
    };
  }
1037898
@Override
    public boolean matches(IAtom atom) {
        boolean val = false;
        boolean matchesLeft = left.matches(atom);
        if (right != null) {
            if ("and".equals(operator) && matchesLeft) {
                boolean matchesRight = right.matches(atom);
                val = matchesLeft && matchesRight;
            } else if ("or".equals(operator)) {
                boolean matchesRight = right.matches(atom);
                val = matchesLeft || matchesRight;
            }
        } else {
            if ("not".equals(operator)) {
                val = (!matchesLeft);
            } else {
                val = matchesLeft;
            }
        }
        return val;
    }
153337
private void compileAssignment(Sequence sequence, TokenList tokens, TokenList.Token t0) {
        // see if it is assign or a range
        List<Variable> range = parseAssignRange(sequence, tokens, t0);

        TokenList.Token t1 = t0.next;
        if (t1.getType() != Type.SYMBOL || t1.getSymbol() != Symbol.ASSIGN)
            throw new ParseError("Expected assignment operator next");

        // Parse the right side of the equation
        TokenList tokensRight = tokens.extractSubList(t1.next, tokens.last);
        compileTokens(sequence, tokensRight);
        if (tokensRight.getLast().getType() != Type.VARIABLE)
            throw new RuntimeException("BUG the last token must be a variable");

        // copy the results into the output
        Variable variableRight = tokensRight.getFirst().getVariable();
        if (range == null) {
            // no range, so copy results into the entire output matrix
            sequence.output = createVariableInferred(t0, variableRight);
            sequence.addOperation(Operation.copy(variableRight, sequence.output));
        } else {
            // a sub-matrix range is specified.  Copy into that inner part
            if (t0.getType() == Type.WORD) {
                throw new ParseError("Can't do lazy variable initialization with submatrices. " + t0.getWord());
            }
            sequence.addOperation(Operation.copy(variableRight, t0.getVariable(), range));
        }
    }
1250882
public static boolean isVariable(ASTNode expression, String pattern) {
        return (expression instanceof VariableExpression && ((VariableExpression) expression).getName().matches(pattern));
    }
724599
private boolean containsNumericMatcher(String matcherExpression) {
        for (String numericMatcher : numericMatchers) {
            if (matcherExpression.contains(numericMatcher)) {
                return true;
            }
        }

        return false;
    }
1315470
public static <T extends ModifierReviewable.ForMethodDescription> ElementMatcher.Junction<T> isVarArgs() {
        return new ModifierMatcher<T>(ModifierMatcher.Mode.VAR_ARGS);
    }
517324
@Override
  public Description matchReturn(ReturnTree tree, VisitorState state) {
    if (!matchWithinClass) {
      return Description.NO_MATCH;
    }
    handler.onMatchReturn(this, tree, state);
    ExpressionTree retExpr = tree.getExpression();
    // let's do quick checks on returned expression first
    if (retExpr == null) {
      return Description.NO_MATCH;
    }
    // now let's check the enclosing method
    TreePath enclosingMethodOrLambda =
        NullabilityUtil.findEnclosingMethodOrLambdaOrInitializer(state.getPath());
    if (enclosingMethodOrLambda == null) {
      throw new RuntimeException("no enclosing method, lambda or initializer!");
    }
    if (!(enclosingMethodOrLambda.getLeaf() instanceof MethodTree
        || enclosingMethodOrLambda.getLeaf() instanceof LambdaExpressionTree)) {
      throw new RuntimeException(
          "return statement outside of a method or lambda! (e.g. in an initializer block)");
    }
    Tree leaf = enclosingMethodOrLambda.getLeaf();
    Symbol.MethodSymbol methodSymbol;
    if (leaf instanceof MethodTree) {
      MethodTree enclosingMethod = (MethodTree) leaf;
      methodSymbol = ASTHelpers.getSymbol(enclosingMethod);
    } else {
      // we have a lambda
      methodSymbol =
          NullabilityUtil.getFunctionalInterfaceMethod(
              (LambdaExpressionTree) leaf, state.getTypes());
    }
    return checkReturnExpression(tree, retExpr, methodSymbol, state);
  }
50714
public static boolean isVariableReplacementPattern(final String value) {
    final Matcher matcher = VARIABLE_REPLACEMENT_PATTERN.matcher(value);
    return matcher.matches();
  }
665588
boolean matchProcessingInstruction(
            final boolean blockMatching,
            final int markupLevel, final int markupBlockIndex) {

        checkMarkupLevel(markupLevel);

        if (this.markupSelectorItem.anyLevel() || markupLevel == 0 || (this.prev != null && this.prev.matchedMarkupLevels[markupLevel - 1])) {
            // This text has not matched yet, but might match, so we should check

            this.matchesThisLevel = this.markupSelectorItem.matchesProcessingInstruction(markupBlockIndex, this.markupBlockMatchingCounter);

            if (matchesPreviousOrCurrentLevel(markupLevel)) {
                // This filter was already matched by a previous level (through an "open" event), so just delegate to next.

                if (this.next != null) {
                    return this.next.matchProcessingInstruction(blockMatching, markupLevel, markupBlockIndex);
                }
                return (blockMatching? true : this.matchesThisLevel);

            } else if (this.matchesThisLevel) {
                // This filter was not matched before. So the fact that it matches now means we need to consume it,
                // therefore not delegating.

                return (this.next == null);

            }

        } else if (matchesPreviousOrCurrentLevel(markupLevel)) {
            // This filter was already matched by a previous level (through an "open" event), so just delegate to next.

            if (this.next != null) {
                return this.next.matchProcessingInstruction(blockMatching, markupLevel, markupBlockIndex);
            }
            return blockMatching;

        }

        return false;

    }