Examine all outer classes in predicates.

When deciding if a particular member is part of the "removed" or
"exact" API surface area, check all outer classes, not just the
direct parent class.

We're using the "exact" output to probe @SystemApi for security
checks, which is why we need this fix.

Test: make -j32 update-api
Bug: 62263906
Change-Id: I385c1cec93523deb46364ae327bc95ac89371b45
diff --git a/src/com/google/doclava/Stubs.java b/src/com/google/doclava/Stubs.java
index 2010315..5c70820 100644
--- a/src/com/google/doclava/Stubs.java
+++ b/src/com/google/doclava/Stubs.java
@@ -1199,12 +1199,17 @@
   public static class RemovedPredicate implements Predicate<MemberInfo> {
     @Override
     public boolean test(MemberInfo member) {
-      final ClassInfo clazz = member.containingClass();
-      final boolean removed = clazz.isRemoved() || member.isRemoved();
-      final boolean clazzVisible = clazz.isPublic() || clazz.isProtected();
-      final boolean memberVisible = member.isPublic() || member.isProtected();
+      ClassInfo clazz = member.containingClass();
 
-      if (removed && clazzVisible && memberVisible) {
+      boolean visible = member.isPublic() || member.isProtected();
+      boolean removed = member.isRemoved();
+      while (clazz != null) {
+        visible &= clazz.isPublic() || clazz.isProtected();
+        removed |= clazz.isRemoved();
+        clazz = clazz.containingClass();
+      }
+
+      if (visible && removed) {
         if (member instanceof MethodInfo) {
           final MethodInfo method = (MethodInfo) member;
           return (method.findOverriddenMethod(method.name(), method.signature()) == null);
@@ -1220,13 +1225,19 @@
   public static class ExactPredicate implements Predicate<MemberInfo> {
     @Override
     public boolean test(MemberInfo member) {
-      final ClassInfo clazz = member.containingClass();
-      final boolean hasShowAnnotation = member.hasShowAnnotation()
-          || member.containingClass().hasShowAnnotation();
-      final boolean clazzVisible = clazz.isPublic() || clazz.isProtected();
-      final boolean memberVisible = member.isPublic() || member.isProtected();
+      ClassInfo clazz = member.containingClass();
 
-      if (hasShowAnnotation && !member.isHiddenOrRemoved() && clazzVisible && memberVisible) {
+      boolean visible = member.isPublic() || member.isProtected();
+      boolean hasShowAnnotation = member.hasShowAnnotation();
+      boolean hiddenOrRemoved = member.isHiddenOrRemoved();
+      while (clazz != null) {
+        visible &= clazz.isPublic() || clazz.isProtected();
+        hasShowAnnotation |= clazz.hasShowAnnotation();
+        hiddenOrRemoved |= clazz.isHiddenOrRemoved();
+        clazz = clazz.containingClass();
+      }
+
+      if (visible && hasShowAnnotation && !hiddenOrRemoved) {
         if (member instanceof MethodInfo) {
           final MethodInfo method = (MethodInfo) member;
           return (method.findOverriddenMethod(method.name(), method.signature()) == null);