Add template method test for class merging

Change-Id: I0569722de9e022af7aab8af868d5accd8c3903e0
diff --git a/src/test/examples/classmerging/TemplateMethodTest.java b/src/test/examples/classmerging/TemplateMethodTest.java
new file mode 100644
index 0000000..ac9de15
--- /dev/null
+++ b/src/test/examples/classmerging/TemplateMethodTest.java
@@ -0,0 +1,31 @@
+// Copyright (c) 2018, 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 classmerging;
+
+public class TemplateMethodTest {
+
+  public static void main(String[] args) {
+    AbstractClass obj = new AbstractClassImpl();
+    obj.foo();
+  }
+
+  private abstract static class AbstractClass {
+
+    public void foo() {
+      System.out.println("In foo on AbstractClass");
+      bar();
+    }
+
+    protected abstract void bar();
+  }
+
+  public static final class AbstractClassImpl extends AbstractClass {
+
+    @Override
+    public void bar() {
+      System.out.println("In bar on AbstractClassImpl");
+    }
+  }
+}
diff --git a/src/test/examples/classmerging/keep-rules.txt b/src/test/examples/classmerging/keep-rules.txt
index f9e6d52..814e889 100644
--- a/src/test/examples/classmerging/keep-rules.txt
+++ b/src/test/examples/classmerging/keep-rules.txt
@@ -10,6 +10,9 @@
 -keep public class classmerging.ExceptionTest {
   public static void main(...);
 }
+-keep public class classmerging.TemplateMethodTest {
+  public static void main(...);
+}
 
 # TODO(herhut): Consider supporting merging of inner-class attributes.
 # -keepattributes *
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java
index d2643cb..0977533 100644
--- a/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java
@@ -146,6 +146,21 @@
     assertEquals(2, numberOfMoveExceptionInstructions);
   }
 
+  @Test
+  public void testTemplateMethodPattern() throws Exception {
+    String main = "classmerging.TemplateMethodTest";
+    Path[] programFiles =
+        new Path[] {
+          CF_DIR.resolve("TemplateMethodTest.class"),
+          CF_DIR.resolve("TemplateMethodTest$AbstractClass.class"),
+          CF_DIR.resolve("TemplateMethodTest$AbstractClassImpl.class")
+        };
+    Set<String> preservedClassNames =
+        ImmutableSet.of(
+            "classmerging.TemplateMethodTest", "classmerging.TemplateMethodTest$AbstractClassImpl");
+    runTest(main, programFiles, preservedClassNames);
+  }
+
   private DexInspector runTest(String main, Path[] programFiles, Set<String> preservedClassNames)
       throws Exception {
     AndroidApp input = readProgramFiles(programFiles);