Add a test that we do not remove abstract methods if they only
shadow library methods.

Bug:
Change-Id: I980b6450f75c69b534058c14b4e7bbf81248ec7b
diff --git a/src/test/examples/shaking17/AbstractProgramClass.java b/src/test/examples/shaking17/AbstractProgramClass.java
new file mode 100644
index 0000000..d3b696b
--- /dev/null
+++ b/src/test/examples/shaking17/AbstractProgramClass.java
@@ -0,0 +1,9 @@
+// Copyright (c) 2017, 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 shaking17;
+
+public abstract class AbstractProgramClass extends shakinglib.AbstractLibraryClass {
+
+  public abstract int abstractMethod();
+}
diff --git a/src/test/examples/shaking17/Shaking.java b/src/test/examples/shaking17/Shaking.java
new file mode 100644
index 0000000..78cc495
--- /dev/null
+++ b/src/test/examples/shaking17/Shaking.java
@@ -0,0 +1,16 @@
+// Copyright (c) 2017, 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 shaking17;
+
+public class Shaking {
+
+  public static void main(String[] args) {
+    Subclass subclass = new Subclass();
+    callTheMethod(subclass);
+  }
+
+  private static void callTheMethod(AbstractProgramClass abstractProgramClass) {
+    System.out.print(abstractProgramClass.abstractMethod());
+  }
+}
diff --git a/src/test/examples/shaking17/Subclass.java b/src/test/examples/shaking17/Subclass.java
new file mode 100644
index 0000000..237dca9
--- /dev/null
+++ b/src/test/examples/shaking17/Subclass.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2017, 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 shaking17;
+
+public class Subclass extends AbstractProgramClass {
+
+  @Override
+  public int abstractMethod() {
+    return 42;
+  }
+}
diff --git a/src/test/examples/shaking17/keep-rules.txt b/src/test/examples/shaking17/keep-rules.txt
new file mode 100644
index 0000000..27dd8f3
--- /dev/null
+++ b/src/test/examples/shaking17/keep-rules.txt
@@ -0,0 +1,9 @@
+# Copyright (c) 2017, 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.
+
+# Keep the application entry point. Get rid of everything that is not
+# reachable from there.
+-keep public class shaking17.Shaking {
+  public static void main(...);
+}
diff --git a/src/test/examples/shakinglib/AbstractLibraryClass.java b/src/test/examples/shakinglib/AbstractLibraryClass.java
new file mode 100644
index 0000000..614b53e
--- /dev/null
+++ b/src/test/examples/shakinglib/AbstractLibraryClass.java
@@ -0,0 +1,9 @@
+// Copyright (c) 2017, 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 shakinglib;
+
+public abstract class AbstractLibraryClass {
+
+  public abstract int abstractMethod();
+}
diff --git a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
index 51b6ab5..ab6d6e2 100644
--- a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
@@ -478,6 +478,12 @@
     inspector.forAllClasses((clazz) -> checkClassAndMemberInDictionary(clazz));
   }
 
+  private static void abstractMethodRemains(DexInspector inspector) {
+    ClassSubject programClass = inspector.clazz("shaking17.AbstractProgramClass");
+    Assert.assertTrue(programClass.isPresent());
+    Assert.assertTrue(
+        programClass.method("int", "abstractMethod", Collections.emptyList()).isPresent());
+  }
 
   private static void assumenosideeffects1CheckOutput(String output1, String output2) {
     Assert.assertEquals("noSideEffectVoid\nnoSideEffectInt\n", output1);
@@ -620,6 +626,7 @@
             "shaking14",
             "shaking15",
             "shaking16",
+            "shaking17",
             "inlining",
             "minification",
             "minifygeneric",
@@ -684,22 +691,17 @@
         .put("shaking11:keep-rules.txt", TreeShakingTest::shaking11OnlyOneClassKept);
     inspections
         .put("shaking11:keep-rules-keep-method.txt", TreeShakingTest::shaking11BothMethodsKept);
-    inspections
-        .put("shaking12:keep-rules.txt",
+    inspections.put("shaking12:keep-rules.txt",
             TreeShakingTest::shaking12OnlyInstantiatedClassesHaveConstructors);
-    inspections
-        .put("shaking13:keep-rules.txt",
+    inspections.put("shaking13:keep-rules.txt",
             TreeShakingTest::shaking13EnsureFieldWritesCorrect);
-    inspections
-        .put("shaking14:keep-rules.txt",
+    inspections.put("shaking14:keep-rules.txt",
             TreeShakingTest::shaking14EnsureRightStaticMethodsLive);
-    inspections.put("shaking15:keep-rules.txt",
-        TreeShakingTest::shaking15testDictionary);
-    inspections
-        .put("annotationremoval:keep-rules.txt",
+    inspections.put("shaking15:keep-rules.txt", TreeShakingTest::shaking15testDictionary);
+    inspections.put("shaking17:keep-rules.txt", TreeShakingTest::abstractMethodRemains);
+    inspections.put("annotationremoval:keep-rules.txt",
             TreeShakingTest::annotationRemovalHasNoInnerClassAnnotations);
-    inspections
-        .put("annotationremoval:keep-rules-keep-innerannotation.txt",
+    inspections.put("annotationremoval:keep-rules-keep-innerannotation.txt",
             TreeShakingTest::annotationRemovalHasAllInnerClassAnnotations);
     inspections
         .put("simpleproto1:keep-rules.txt", TreeShakingTest::simpleproto1UnusedFieldIsGone);