Matches an AST node that is enclosed by some node that matches the given matcher.

<p>TODO(eaftan): This could be used instead of enclosingBlock and enclosingClass.
978007
public static <T extends Tree> Matcher<Tree> enclosingNode(final Matcher<T> matcher) {
    return new Matcher<Tree>() {
      @SuppressWarnings("unchecked") // TODO(cushon): this should take a Class<T>
      @Override
      public boolean matches(Tree t, VisitorState state) {
        TreePath path = state.getPath().getParentPath();
        while (path != null) {
          Tree node = path.getLeaf();
          state = state.withPath(path);
          if (matcher.matches((T) node, state)) {
            return true;
          }
          path = path.getParentPath();
        }
        return false;
      }
    };
  }
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;

    }
1072476
public ResultMatcher matches(final Matcher<?> matcher) {
        return new AbstractResultMatcher(path, configuration) {
            public void doMatch(Object actual) {
                isPresent(actual);
                Node node = getNode(actual);
                assertThat("Node \"" + path + "\" does not match.", node.getValue(), (Matcher<? super Object>) matcher);
            }
        };

    }
795182
private static Matcher<Tree> shouldAllow(RestrictedApi api) {
    try {
      return Matchers.hasAnyAnnotation(api.whitelistAnnotations());
    } catch (MirroredTypesException e) {
      return Matchers.hasAnyAnnotation(e.getTypeMirrors());
    }
  }
430568
public static <T extends Tree> Matcher<T> isSame(final Tree t) {
    return new Matcher<T>() {
      @Override
      public boolean matches(T tree, VisitorState state) {
        return tree == t;
      }
    };
  }
1116889
function matchSelector(element, selector) {
        if (!element || element.nodeType !== 1) {
            return false
        }

        var parent,
            match,
            matchesSelector = element.webkitMatchesSelector || element.matchesSelector;

        if (matchesSelector) {
            match = matchesSelector.call(element, selector)
        } else {
            parent = element.parentNode;
            match = !! parent.querySelector(selector);
        }

        return match;
    }
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);
  }
312148
def match(self, node, results=None):
        """"""
        if not isinstance(node, Leaf):
            return False
        return BasePattern.match(self, node, results)
512275
static Matcher flattenNestedOr(Matcher matcher) {
    if (matcher instanceof OrMatcher) {
      List<Matcher> matchers = matcher.<OrMatcher>as().matchers();
      List<Matcher> ms = new ArrayList<>();
      for (Matcher m : matchers) {
        if (m instanceof OrMatcher) {
          ms.addAll(m.<OrMatcher>as().matchers());
        } else {
          ms.add(m);
        }
      }
      return OrMatcher.create(ms);
    }
    return matcher;
  }
140050
function containsNode(outerNode, innerNode) {
  if (!outerNode || !innerNode) {
    return false;
  } else if (outerNode === innerNode) {
    return true;
  } else if (isTextNode(outerNode)) {
    return false;
  } else if (isTextNode(innerNode)) {
    return containsNode(outerNode, innerNode.parentNode);
  } else if (outerNode.contains) {
    return outerNode.contains(innerNode);
  } else if (outerNode.compareDocumentPosition) {
    return !!(outerNode.compareDocumentPosition(innerNode) & 16);
  } else {
    return false;
  }
}
589270
function getClosestNode (element, method, selector) {
        do {
            element = element[method]
        } while (element && ((selector && !matches(element, selector)) || !util.isElement(element)))
        return element
    }
191632
public static <T extends Tree> Matcher<T> isSubtypeOf(Class<?> clazz) {
    return new IsSubtypeOf<>(typeFromClass(clazz));
  }
630575
public static final <T extends Tree> Matcher<T> inSynchronized() {
    return new Matcher<T>() {
      @Override
      public boolean matches(T tree, VisitorState state) {
        SynchronizedTree synchronizedTree =
            ASTHelpers.findEnclosingNode(state.getPath(), SynchronizedTree.class);
        if (synchronizedTree != null) {
          return true;
        }

        MethodTree methodTree = ASTHelpers.findEnclosingNode(state.getPath(), MethodTree.class);
        return methodTree != null
            && methodTree.getModifiers().getFlags().contains(Modifier.SYNCHRONIZED);
      }
    };
  }
625001
@Override
  public Description matchAnnotation(AnnotationTree tree, VisitorState state) {
    if (!ANNOTATION_MATCHER.matches(tree, state)) {
      return Description.NO_MATCH;
    }

    MethodTree methodTree = ASTHelpers.findEnclosingNode(state.getPath(), MethodTree.class);
    if (methodTree == null) {
      return Description.NO_MATCH;
    }

    MethodSymbol methodSym = ASTHelpers.getSymbol(methodTree);
    if (methodSym == null) {
      return Description.NO_MATCH;
    }

    if (!methodSym.getModifiers().contains(Modifier.ABSTRACT)) {
      return Description.NO_MATCH;
    }

    // Match, find the matched annotation to use for the error message.
    Symbol annotationSym = ASTHelpers.getSymbol(tree);
    if (annotationSym == null) {
      return Description.NO_MATCH;
    }

    return buildDescription(tree)
        .setMessage(
            String.format(
                "@%s cannot be applied to an abstract method", annotationSym.getSimpleName()))
        .build();
  }
880829
function SingleMatcherIterator(i, node, match) {
  this.i = i;
  this.n = node;
  this.m = match;
  this.f = true;
}
682957
private static Matcher<UnaryTree> expressionFromUnaryTree(
      final Matcher<ExpressionTree> exprMatcher) {
    return new Matcher<UnaryTree>() {
      @Override
      public boolean matches(UnaryTree tree, VisitorState state) {
        return exprMatcher.matches(tree.getExpression(), state);
      }
    };
  }
267111
boolean matchComment(
            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.matchesComment(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.matchComment(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.matchComment(blockMatching, markupLevel, markupBlockIndex);
            }
            return blockMatching;

        }

        return false;

    }