NestBasedAccessControl Anonymous Inner class support

- Added tests for anonymous inner class
- Turns out anonymous inner classes worked out of the box
- Added a simpler test to debug simple cases
- change Nest tests packaging to follow convention
(all in package named nestHostExample instead of no package)
- change Java 11 tests build to avoid committing all class files

Bug: 130529338
Change-Id: Ic69b5aa730c6168e993e5deacf3f1b7b074196b4
diff --git a/build.gradle b/build.gradle
index 158dc7b..6ef713e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -68,8 +68,15 @@
     test {
         java {
             srcDirs = [
-                'src/test/java',
-                'build/generated/test/java',
+                    'src/test/java',
+                    'build/generated/test/java',
+            ]
+        }
+    }
+    java11 {
+        java {
+            srcDirs = [
+                    'src/test/examplesJava11'
             ]
         }
     }
@@ -218,6 +225,7 @@
     implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
     implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
     testCompile sourceSets.examples.output
+    testCompile sourceSets.java11.output
     testCompile "junit:junit:$junitVersion"
     testCompile group: 'org.smali', name: 'smali', version: smaliVersion
     testCompile files('third_party/jasmin/jasmin-2.4.jar')
@@ -491,6 +499,21 @@
     }
 }
 
+tasks.named(sourceSets.java11.compileJavaTaskName).get().configure {
+    options.fork = true
+    options.forkOptions.jvmArgs = []
+    if (OperatingSystem.current().isLinux()) {
+        options.forkOptions.javaHome = file('third_party/openjdk/jdk-11/Linux')
+    } else if (OperatingSystem.current().isMacOsX()) {
+        options.forkOptions.javaHome = file('third_party/openjdk/jdk-11/Mac')
+    } else {
+        options.forkOptions.javaHome = file('third_party/openjdk/jdk-11/Windows')
+    }
+    sourceCompatibility = JavaVersion.VERSION_11
+    targetCompatibility = JavaVersion.VERSION_11
+}
+
+
 if (!project.hasProperty('without_error_prone') &&
         // Don't enable error prone on Java 8 as the plugin setup does not support it.
         !org.gradle.internal.jvm.Jvm.current().javaVersion.java8) {
@@ -1292,7 +1315,7 @@
         task "jar_examplesJava11_${name}"(type: Jar) {
             archiveName = jarName
             destinationDir = exampleOutputDir
-            from "src/test/examplesJava11"  // Java 11 classes
+            from "build/classes/java/java11/"  // Java 11 classes
             include "**/" + name + "/**/*.class"
         }
     }
@@ -2110,45 +2133,3 @@
 
     dependsOn compile_Java9examples
 }
-
-// Same as above for Java 11
-// ./tools/gradle.py -Pjava11Home=<java 11 home> buildJava11Tests
-task buildJava11Tests {
-    def javacOutputFolder = getTemporaryDir();
-    def examplesDir = file("src/test/examplesJava11")
-
-    task "compile_Java11examples"(type: JavaCompile) {
-        doFirst {
-            if (!project.hasProperty('java11Home') || project.property('java11Home').isEmpty()) {
-                throw new GradleException("Set java11Home property.")
-            }
-        }
-
-        source = fileTree(dir: examplesDir, include: '**/*.java')
-        destinationDir = javacOutputFolder
-        classpath = sourceSets.main.compileClasspath
-        options.compilerArgs += ["-Xlint:-options"]
-        sourceCompatibility = JavaVersion.VERSION_11
-        targetCompatibility = JavaVersion.VERSION_11
-        options.fork = true
-
-        if (project.hasProperty('java11Home')) {
-            options.forkOptions.javaHome = file(getProperty('java11Home'))
-        }
-
-        doLast {
-            def classfileFrom = copySpec {
-                from javacOutputFolder
-                include "**/*.class"
-            }
-            copy {
-                into examplesDir
-                with classfileFrom
-            }
-            delete javacOutputFolder
-            println "Warning: in my cases nested classes were not showed on IntelliJ"
-        }
-    }
-
-    dependsOn compile_Java11examples
-}
diff --git a/src/test/examplesJava11/nestHostExample/BasicNestHostWithAnonymousInnerClass.java b/src/test/examplesJava11/nestHostExample/BasicNestHostWithAnonymousInnerClass.java
new file mode 100644
index 0000000..f97282c
--- /dev/null
+++ b/src/test/examplesJava11/nestHostExample/BasicNestHostWithAnonymousInnerClass.java
@@ -0,0 +1,43 @@
+// Copyright (c) 2019, 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 nestHostExample;
+
+public class BasicNestHostWithAnonymousInnerClass {
+
+  private String method() {
+    return "hostMethod";
+  }
+
+  private static String staticMethod() {
+    return "staticHostMethod";
+  }
+
+  private String field = "field";
+  private static String staticField = "staticField";
+
+  public static InterfaceForAnonymousClass createAnonymousNestedInstance() {
+    return new InterfaceForAnonymousClass() {
+      public String accessOuter(BasicNestHostWithAnonymousInnerClass o) {
+        return o.field
+            + o.staticField
+            + BasicNestHostWithAnonymousInnerClass.staticField
+            + o.method()
+            + o.staticMethod()
+            + BasicNestHostWithAnonymousInnerClass.staticMethod();
+      }
+    };
+  }
+
+  public interface InterfaceForAnonymousClass {
+    String accessOuter(BasicNestHostWithAnonymousInnerClass o);
+  }
+
+  public static void main(String[] args) {
+    BasicNestHostWithAnonymousInnerClass outer = new BasicNestHostWithAnonymousInnerClass();
+    InterfaceForAnonymousClass anonymousInner =
+        BasicNestHostWithAnonymousInnerClass.createAnonymousNestedInstance();
+    System.out.println(anonymousInner.accessOuter(outer));
+  }
+}
diff --git a/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClass.java b/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClass.java
new file mode 100644
index 0000000..64aa388
--- /dev/null
+++ b/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClass.java
@@ -0,0 +1,76 @@
+// Copyright (c) 2019, 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 nestHostExample;
+
+public class BasicNestHostWithInnerClass {
+
+  private String method() {
+    return "hostMethod";
+  }
+
+  private static String staticMethod() {
+    return "staticHostMethod";
+  }
+
+  private String field;
+  private static String staticField = "staticField";
+
+  private BasicNestHostWithInnerClass(String field) {
+    this.field = field;
+  }
+
+  public static BasicNestedClass createNestedInstance(String field) {
+    return new BasicNestedClass(field);
+  }
+
+  @SuppressWarnings("static-access") // we want to test that too.
+  public String accessNested(BasicNestedClass o) {
+    return o.field
+        + o.staticField
+        + BasicNestedClass.staticField
+        + o.method()
+        + o.staticMethod()
+        + BasicNestedClass.staticMethod();
+  }
+
+  public static class BasicNestedClass {
+    private String method() {
+      return "nestMethod";
+    }
+
+    private static String staticMethod() {
+      return "staticNestMethod";
+    }
+
+    private String field;
+    private static String staticField = "staticNestField";
+
+    private BasicNestedClass(String field) {
+      this.field = field;
+    }
+
+    public static BasicNestHostWithInnerClass createOuterInstance(String field) {
+      return new BasicNestHostWithInnerClass(field);
+    }
+
+    @SuppressWarnings("static-access") // we want to test that too.
+    public String accessOuter(BasicNestHostWithInnerClass o) {
+      return o.field
+          + o.staticField
+          + BasicNestedClass.staticField
+          + o.method()
+          + o.staticMethod()
+          + BasicNestedClass.staticMethod();
+    }
+
+    public static void main(String[] args) {
+      BasicNestHostWithInnerClass outer = BasicNestedClass.createOuterInstance("field");
+      BasicNestedClass inner = BasicNestHostWithInnerClass.createNestedInstance("nest1SField");
+
+      System.out.println(outer.accessNested(inner));
+      System.out.println(inner.accessOuter(outer));
+    }
+  }
+}
diff --git a/src/test/examplesJava11/nestHostExample/NestHostExample$NestMemberInner$NestMemberInnerInner.class b/src/test/examplesJava11/nestHostExample/NestHostExample$NestMemberInner$NestMemberInnerInner.class
deleted file mode 100644
index 0259744..0000000
--- a/src/test/examplesJava11/nestHostExample/NestHostExample$NestMemberInner$NestMemberInnerInner.class
+++ /dev/null
Binary files differ
diff --git a/src/test/examplesJava11/nestHostExample/NestHostExample$NestMemberInner.class b/src/test/examplesJava11/nestHostExample/NestHostExample$NestMemberInner.class
deleted file mode 100644
index b9ef04a..0000000
--- a/src/test/examplesJava11/nestHostExample/NestHostExample$NestMemberInner.class
+++ /dev/null
Binary files differ
diff --git a/src/test/examplesJava11/nestHostExample/NestHostExample$StaticNestInterfaceInner.class b/src/test/examplesJava11/nestHostExample/NestHostExample$StaticNestInterfaceInner.class
deleted file mode 100644
index c158f44..0000000
--- a/src/test/examplesJava11/nestHostExample/NestHostExample$StaticNestInterfaceInner.class
+++ /dev/null
Binary files differ
diff --git a/src/test/examplesJava11/nestHostExample/NestHostExample$StaticNestMemberInner$StaticNestMemberInnerInner.class b/src/test/examplesJava11/nestHostExample/NestHostExample$StaticNestMemberInner$StaticNestMemberInnerInner.class
deleted file mode 100644
index 13d5b4c..0000000
--- a/src/test/examplesJava11/nestHostExample/NestHostExample$StaticNestMemberInner$StaticNestMemberInnerInner.class
+++ /dev/null
Binary files differ
diff --git a/src/test/examplesJava11/nestHostExample/NestHostExample$StaticNestMemberInner.class b/src/test/examplesJava11/nestHostExample/NestHostExample$StaticNestMemberInner.class
deleted file mode 100644
index c75b0d3..0000000
--- a/src/test/examplesJava11/nestHostExample/NestHostExample$StaticNestMemberInner.class
+++ /dev/null
Binary files differ
diff --git a/src/test/examplesJava11/nestHostExample/NestHostExample.class b/src/test/examplesJava11/nestHostExample/NestHostExample.class
deleted file mode 100644
index 3d7c788..0000000
--- a/src/test/examplesJava11/nestHostExample/NestHostExample.class
+++ /dev/null
Binary files differ
diff --git a/src/test/examplesJava11/nestHostExample/NestHostExample.java b/src/test/examplesJava11/nestHostExample/NestHostExample.java
index 1fdfbaf..a9863cc 100644
--- a/src/test/examplesJava11/nestHostExample/NestHostExample.java
+++ b/src/test/examplesJava11/nestHostExample/NestHostExample.java
@@ -2,6 +2,8 @@
 // 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 nestHostExample;
+
 // Warning: This requires Java 9+ to be compiled (private interface methods)
 // This file builds all the possible combinations of private members:
 // - static VS non-static
diff --git a/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAccessControlTest.java b/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAccessControlTest.java
index 41d7876..2fb0a08 100644
--- a/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAccessControlTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAccessControlTest.java
@@ -39,7 +39,7 @@
         .addProgramFiles(Paths.get(EXAMPLE_DIR, "nestHostExample" + JAR_EXTENSION))
         .setMinApi(parameters.getRuntime())
         .compile()
-        .run(parameters.getRuntime(), "NestHostExample")
+        .run(parameters.getRuntime(), "nestHostExample.NestHostExample")
         .assertFailureWithErrorThatMatches(containsString("IllegalAccessError"));
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAttributesTest.java b/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAttributesTest.java
index e5b20bc..208e0ab 100644
--- a/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAttributesTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAttributesTest.java
@@ -8,6 +8,7 @@
 import static junit.framework.TestCase.assertEquals;
 import static junit.framework.TestCase.assertNull;
 import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertFalse;
 
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
@@ -15,6 +16,7 @@
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.graph.DexClass;
+import com.google.common.collect.ImmutableSet;
 import java.nio.file.Paths;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -45,19 +47,24 @@
         .compile()
         .inspect(
             inspector -> {
-              assertEquals(6, inspector.allClasses().size());
+              assertEquals(11, inspector.allClasses().size());
+              ImmutableSet<String> outerClassNames =
+                  ImmutableSet.of(
+                      "NestHostExample",
+                      "BasicNestHostWithInnerClass",
+                      "BasicNestHostWithAnonymousInnerClass");
               inspector.forAllClasses(
                   classSubject -> {
                     DexClass dexClass = classSubject.getDexClass();
                     assertTrue(dexClass.isInANest());
-                    if (dexClass.type.getName().equals("NestHostExample")) {
+                    if (outerClassNames.contains(dexClass.type.getName())) {
                       assertNull(dexClass.getNestHostClassAttribute());
-                      assertEquals(5, dexClass.getNestMembersClassAttributes().size());
+                      assertFalse(dexClass.getNestMembersClassAttributes().isEmpty());
                     } else {
                       assertTrue(dexClass.getNestMembersClassAttributes().isEmpty());
-                      assertEquals(
-                          "NestHostExample",
-                          dexClass.getNestHostClassAttribute().getNestHost().getName());
+                      assertTrue(
+                          outerClassNames.contains(
+                              dexClass.getNestHostClassAttribute().getNestHost().getName()));
                     }
                   });
             });