Hide Java 8 interfaces methods to generators.

Current GWT generators do not expect default nor static methods
in interfaces. This patch makes the safest choice which is to hide
those methods.

Bug: #9371
Bug-Link: https://github.com/gwtproject/gwt/issues/9371
Change-Id: I623358e5cd9135e91186dd84e02fb3909a4a8538
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationUnitTypeOracleUpdater.java b/dev/core/src/com/google/gwt/dev/javac/CompilationUnitTypeOracleUpdater.java
index f63e037..b4496f1 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationUnitTypeOracleUpdater.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationUnitTypeOracleUpdater.java
@@ -887,6 +887,7 @@
      *
      * These differences also show up when using java.lang.reflect to look at types.
      */
+    boolean isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
     if (signature != null) {
       // If we have a signature, use it for superclass and interfaces
       SignatureReader reader = new SignatureReader(signature);
@@ -903,7 +904,7 @@
       }
     } else {
       // Set the super type for non-interfaces
-      if ((access & Opcodes.ACC_INTERFACE) == 0) {
+      if (!isInterface) {
         String superInternalName = classData.getSuperInternalName();
         assert Name.isInternalName(superInternalName);
         if (superInternalName != null) {
@@ -927,7 +928,7 @@
             unresolvedType, (JClassType) possiblySubstituteRawType(interfaceType));
       }
     }
-    if (((access & Opcodes.ACC_INTERFACE) == 0) && unresolvedType.getSuperclass() == null) {
+    if (!isInterface && unresolvedType.getSuperclass() == null) {
       // Only Object or interfaces should not have a superclass
       assert "java/lang/Object".equals(classData.getInternalName());
     }
@@ -935,6 +936,11 @@
     // Process methods
     for (CollectMethodData method : classData.getMethods()) {
       TreeLogger branch = logger.branch(TreeLogger.SPAM, "Resolving method " + method.getName());
+      // TODO(rluble): Allow the users to ask for Java 8 features. For now these are filtered out.
+      if (isInterface && isJava8InterfaceMethod(method)) {
+        logger.log(TreeLogger.Type.SPAM, "Ignoring Java 8 interface method " + method.getName());
+        continue;
+      }
       if (!resolveMethod(branch, unresolvedType, method, typeParamLookup, context)) {
         // Already logged.
         return false;
@@ -951,10 +957,15 @@
         return false;
       }
     }
-
     return true;
   }
 
+  private boolean isJava8InterfaceMethod(CollectMethodData method) {
+    // (Normal) interface methods are abstract. Java 8 introduced the ability to declare default
+    // methods and static methods both of which are exposed as non abstract methods.
+    return (method.getAccess() & Opcodes.ACC_ABSTRACT) == 0;
+  }
+
   private boolean resolveClass(
       TreeLogger logger, JType unresolvedType, TypeOracleBuildContext context) {
     if (!(unresolvedType instanceof JClassType)) {
diff --git a/dev/core/test/com/google/gwt/dev/javac/CompilationUnitTypeOracleUpdaterFromSourceTest.java b/dev/core/test/com/google/gwt/dev/javac/CompilationUnitTypeOracleUpdaterFromSourceTest.java
index 6f947c3..568489b 100644
--- a/dev/core/test/com/google/gwt/dev/javac/CompilationUnitTypeOracleUpdaterFromSourceTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/CompilationUnitTypeOracleUpdaterFromSourceTest.java
@@ -17,6 +17,7 @@
 
 import com.google.gwt.core.ext.typeinfo.JClassType;
 import com.google.gwt.core.ext.typeinfo.TypeOracleException;
+import com.google.gwt.thirdparty.guava.common.base.Joiner;
 
 /**
  * Tests for {@link TypeOracleUpdater} when provided sources.
@@ -183,6 +184,26 @@
     assertEquals(1, typeOracle.getTypes().length);
   }
 
+  public void testJava8InterfaceExclusions() throws TypeOracleException {
+    String java8Interface = Joiner.on("\n").join(
+        "package test.java8;",
+        "interface Java8Interface {",
+        "  Object field = new Object();",
+        "  final int constant = 1;",
+        "  void m();",
+        "  default void n() {};",
+        "  static void o() {};",
+        "}");
+    addResource("test.java8.Java8Interface", java8Interface);
+    resources.add(CU_Object);
+    buildTypeOracle();
+
+    assertEquals(1, typeOracle.findType("test.java8.Java8Interface").getMethods().length);
+    assertEquals("m", typeOracle.findType("test.java8.Java8Interface").getMethods()[0].getName());
+    assertNotNull(typeOracle.findType(CU_Object.getTypeName()));
+    assertEquals(2, typeOracle.getTypes().length);
+  }
+
   @Override
   protected void buildTypeOracle() throws TypeOracleException {
     typeOracle = TypeOracleTestingUtils.buildTypeOracle(createTreeLogger(),