Revert "[KeepAnno] Remove KeepForApi default member targets on empty classes"

This reverts commit d729316fcba981d0fa83881094ecc10dc0ec5f16.

Reason for revert: test failures due to missing API

Change-Id: I7be25424812edca914a76823e68e57e291e643ff
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
index cf705ed..bc466c5 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.keepanno.asm;
 
-import com.android.tools.r8.keepanno.annotations.KeepItemKind;
 import com.android.tools.r8.keepanno.ast.AccessVisibility;
 import com.android.tools.r8.keepanno.ast.AnnotationConstants;
 import com.android.tools.r8.keepanno.ast.AnnotationConstants.Binding;
@@ -92,9 +91,6 @@
   private static class KeepEdgeClassVisitor extends ClassVisitor {
     private final Parent<KeepDeclaration> parent;
     private String className;
-    private List<AnnotationVisitorBase> annotationVisitors = new ArrayList<>();
-    private boolean done = false;
-    private boolean hasMembers = false;
 
     KeepEdgeClassVisitor(Parent<KeepDeclaration> parent) {
       super(ASM_VERSION);
@@ -105,17 +101,6 @@
       return binaryName.replace('/', '.');
     }
 
-    public boolean classHasMembers() {
-      assert done;
-      return hasMembers;
-    }
-
-    @Override
-    public void visitEnd() {
-      done = true;
-      annotationVisitors.forEach(a -> a.onClassVisitEnd(this));
-    }
-
     @Override
     public void visit(
         int version,
@@ -134,28 +119,20 @@
       if (visible) {
         return null;
       }
-      AnnotationVisitorBase annotationVisitor = determineAnnotationVisitor(descriptor);
-      if (annotationVisitor != null) {
-        annotationVisitors.add(annotationVisitor);
-      }
-      return annotationVisitor;
-    }
-
-    private AnnotationVisitorBase determineAnnotationVisitor(String descriptor) {
       if (descriptor.equals(Edge.DESCRIPTOR)) {
         return new KeepEdgeVisitor(parent::accept, this::setContext);
       }
-      if (descriptor.equals(UsesReflection.DESCRIPTOR)) {
+      if (descriptor.equals(AnnotationConstants.UsesReflection.DESCRIPTOR)) {
         KeepClassItemPattern classItem =
             KeepClassItemPattern.builder()
                 .setClassNamePattern(KeepQualifiedClassNamePattern.exact(className))
                 .build();
         return new UsesReflectionVisitor(parent::accept, this::setContext, classItem);
       }
-      if (descriptor.equals(ForApi.DESCRIPTOR)) {
+      if (descriptor.equals(AnnotationConstants.ForApi.DESCRIPTOR)) {
         return new ForApiClassVisitor(parent::accept, this::setContext, className);
       }
-      if (descriptor.equals(UsedByReflection.DESCRIPTOR)
+      if (descriptor.equals(AnnotationConstants.UsedByReflection.DESCRIPTOR)
           || descriptor.equals(AnnotationConstants.UsedByNative.DESCRIPTOR)) {
         return new UsedByReflectionClassVisitor(
             descriptor, parent::accept, this::setContext, className);
@@ -178,14 +155,12 @@
     @Override
     public MethodVisitor visitMethod(
         int access, String name, String descriptor, String signature, String[] exceptions) {
-      hasMembers = true;
       return new KeepEdgeMethodVisitor(parent::accept, className, name, descriptor);
     }
 
     @Override
     public FieldVisitor visitField(
         int access, String name, String descriptor, String signature, Object value) {
-      hasMembers = true;
       return new KeepEdgeFieldVisitor(parent::accept, className, name, descriptor);
     }
   }
@@ -345,8 +320,6 @@
       super(ASM_VERSION);
     }
 
-    public void onClassVisitEnd(KeepEdgeClassVisitor visitor) {}
-
     public abstract String getAnnotationName();
 
     private String errorMessagePrefix() {
@@ -468,6 +441,8 @@
       addContext.accept(metaInfoBuilder);
       // The class context/holder is the annotated class.
       visit(Item.className, className);
+      // The default kind is to target the class and its members.
+      visitEnum(null, Kind.DESCRIPTOR, Kind.CLASS_AND_MEMBERS);
     }
 
     @Override
@@ -503,16 +478,9 @@
     }
 
     @Override
-    public void onClassVisitEnd(KeepEdgeClassVisitor visitor) {
-      if (getKind() == null) {
-        // The default kind is to target the class and its members if any members exist.
-        KeepItemKind defaultKind =
-            visitor.classHasMembers() ? KeepItemKind.CLASS_AND_MEMBERS : KeepItemKind.ONLY_CLASS;
-        visitEnum(null, Kind.DESCRIPTOR, defaultKind.name());
-      }
+    public void visitEnd() {
       if (!getKind().equals(Kind.ONLY_CLASS) && isDefaultMemberDeclaration()) {
         // If no member declarations have been made, set public & protected as the default.
-        // Only do so if the class actually has any members.
         AnnotationVisitor v = visitArray(Item.memberAccess);
         v.visitEnum(null, MemberAccess.DESCRIPTOR, MemberAccess.PUBLIC);
         v.visitEnum(null, MemberAccess.DESCRIPTOR, MemberAccess.PROTECTED);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleInfo.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleInfo.java
index 29d745b..6dcde1d 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleInfo.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleInfo.java
@@ -5,6 +5,7 @@
 package com.android.tools.r8.profile.art;
 
 import com.android.tools.r8.keepanno.annotations.KeepForApi;
+import com.android.tools.r8.keepanno.annotations.KeepItemKind;
 
-@KeepForApi
+@KeepForApi(kind = KeepItemKind.ONLY_CLASS)
 public interface ArtProfileClassRuleInfo {}
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepForApiWithoutMembersTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepForApiWithoutMembersTest.java
deleted file mode 100644
index e715fff..0000000
--- a/src/test/java/com/android/tools/r8/keepanno/KeepForApiWithoutMembersTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.keepanno;
-
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestDiagnosticMessages;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.keepanno.annotations.KeepForApi;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.StringUtils;
-import com.google.common.collect.ImmutableList;
-import java.util.List;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class KeepForApiWithoutMembersTest extends TestBase {
-
-  static final String EXPECTED = StringUtils.lines("true");
-
-  private final TestParameters parameters;
-
-  @Parameterized.Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withDefaultRuntimes().withApiLevel(AndroidApiLevel.B).build();
-  }
-
-  public KeepForApiWithoutMembersTest(TestParameters parameters) {
-    this.parameters = parameters;
-  }
-
-  @Test
-  public void testReference() throws Exception {
-    testForRuntime(parameters)
-        .addProgramClasses(getInputClasses())
-        .run(parameters.getRuntime(), TestClass.class)
-        .assertSuccessWithOutput(EXPECTED);
-  }
-
-  @Test
-  public void testWithRuleExtraction() throws Exception {
-    testForR8(parameters.getBackend())
-        .enableExperimentalKeepAnnotations()
-        .addProgramClasses(getInputClasses())
-        .addKeepMainRule(TestClass.class)
-        .setMinApi(parameters)
-        .compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoInfos)
-        .run(parameters.getRuntime(), TestClass.class)
-        .assertSuccessWithOutput(EXPECTED);
-  }
-
-  public List<Class<?>> getInputClasses() {
-    return ImmutableList.of(TestClass.class, EmptyInterface.class, A.class);
-  }
-
-  @KeepForApi
-  interface EmptyInterface {}
-
-  static class A implements EmptyInterface {}
-
-  static class TestClass {
-
-    public static void main(String[] args) throws Exception {
-      System.out.println(new A() instanceof EmptyInterface);
-    }
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/keepanno/UsedByReflectionWithoutMembersTest.java b/src/test/java/com/android/tools/r8/keepanno/UsedByReflectionWithoutMembersTest.java
deleted file mode 100644
index 7fa44ba..0000000
--- a/src/test/java/com/android/tools/r8/keepanno/UsedByReflectionWithoutMembersTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.keepanno;
-
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestDiagnosticMessages;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.keepanno.annotations.UsedByReflection;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.StringUtils;
-import com.google.common.collect.ImmutableList;
-import java.util.List;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class UsedByReflectionWithoutMembersTest extends TestBase {
-
-  static final String EXPECTED = StringUtils.lines("true");
-
-  private final TestParameters parameters;
-
-  @Parameterized.Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withDefaultRuntimes().withApiLevel(AndroidApiLevel.B).build();
-  }
-
-  public UsedByReflectionWithoutMembersTest(TestParameters parameters) {
-    this.parameters = parameters;
-  }
-
-  @Test
-  public void testReference() throws Exception {
-    testForRuntime(parameters)
-        .addProgramClasses(getInputClasses())
-        .run(parameters.getRuntime(), TestClass.class)
-        .assertSuccessWithOutput(EXPECTED);
-  }
-
-  @Test
-  public void testWithRuleExtraction() throws Exception {
-    testForR8(parameters.getBackend())
-        .enableExperimentalKeepAnnotations()
-        .addProgramClasses(getInputClasses())
-        .addKeepMainRule(TestClass.class)
-        .setMinApi(parameters)
-        .compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoInfos)
-        .run(parameters.getRuntime(), TestClass.class)
-        .assertSuccessWithOutput(EXPECTED);
-  }
-
-  public List<Class<?>> getInputClasses() {
-    return ImmutableList.of(TestClass.class, EmptyInterface.class, A.class);
-  }
-
-  @UsedByReflection
-  interface EmptyInterface {}
-
-  static class A implements EmptyInterface {}
-
-  static class TestClass {
-
-    public static void main(String[] args) throws Exception {
-      System.out.println(new A() instanceof EmptyInterface);
-    }
-  }
-}