Avoid double printing of member rules for -whyareyoukeeping

Change-Id: I7a91b1fce44b1cd91c4d5fea8a8f59b1dfa9a838
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepReason.java b/src/main/java/com/android/tools/r8/shaking/KeepReason.java
index dc21146..78ef9e9 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepReason.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepReason.java
@@ -77,10 +77,10 @@
     @Override
     public void print(ReasonFormatter formatter) {
       formatter.addReason("referenced in keep rule:");
-      formatter.addMessage("  " + keepRule + " {");
+      formatter.addMessage("  " + keepRule.toShortString() + " {");
       int ruleCount = 0;
       for (ProguardMemberRule memberRule : keepRule.getMemberRules()) {
-        formatter.addMessage("    " + memberRule);
+        formatter.addMessage("    " + memberRule + ";");
         if (++ruleCount > 10) {
           formatter.addMessage("      <...>");
           break;
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java b/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java
index 653f0cf..8de361e 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java
@@ -249,7 +249,7 @@
     return result;
   }
 
-  protected StringBuilder append(StringBuilder builder) {
+  protected StringBuilder append(StringBuilder builder, boolean includeMemberRules) {
     StringUtils.appendNonEmpty(builder, "@", classAnnotation, null);
     StringUtils.appendNonEmpty(builder, "", classAccessFlags, null);
     StringUtils.appendNonEmpty(builder, "!", negatedClassAccessFlags.toString().replace(" ", " !"),
@@ -269,18 +269,27 @@
       builder.append(' ');
       builder.append(inheritanceClassName);
     }
-    builder.append(" {\n");
-    memberRules.forEach(memberRule -> {
-      builder.append("  ");
-      builder.append(memberRule);
-      builder.append(";\n");
-    });
-    builder.append("}");
+    if (includeMemberRules) {
+      builder.append(" {\n");
+      memberRules.forEach(memberRule -> {
+        builder.append("  ");
+        builder.append(memberRule);
+        builder.append(";\n");
+      });
+      builder.append("}");
+    }
     return builder;
   }
 
+  /**
+   * Short String representation without member rules.
+   */
+  public String toShortString() {
+    return append(new StringBuilder(), false).toString();
+  }
+
   @Override
   public String toString() {
-    return append(new StringBuilder()).toString();
+    return append(new StringBuilder(), true).toString();
   }
 }
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
index d4d4bcb..54b90b2 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
@@ -604,7 +604,7 @@
       builder.append('\n');
     }
     for (ProguardConfigurationRule rule : rules) {
-      rule.append(builder);
+      rule.append(builder, true);
       builder.append('\n');
     }
     return builder.toString();
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
index ddc55ab..ce1840f 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
@@ -66,17 +66,12 @@
   }
 
   @Override
-  protected StringBuilder append(StringBuilder builder) {
+  protected StringBuilder append(StringBuilder builder, boolean includeMemberRules) {
     builder.append("-");
     builder.append(typeString());
     StringUtils.appendNonEmpty(builder, ",", modifierString(), null);
     builder.append(' ');
-    super.append(builder);
+    super.append(builder, includeMemberRules);
     return builder;
   }
-
-  @Override
-  public String toString() {
-    return append(new StringBuilder()).toString();
-  }
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java b/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java
new file mode 100644
index 0000000..8308702
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java
@@ -0,0 +1,42 @@
+// 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 com.android.tools.r8.shaking.whyareyoukeeping;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.google.common.collect.ImmutableList;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.nio.charset.Charset;
+import org.junit.Test;
+
+class A {
+
+}
+
+public class WhyAreYouKeepingTest extends TestBase {
+  @Test
+  public void test() throws Exception {
+    String proguardConfig = String.join("\n", ImmutableList.of(
+        "-keep class " + A.class.getCanonicalName() + " { *; }",
+        "-whyareyoukeeping class " + A.class.getCanonicalName()
+    ));
+    PrintStream stdout = System.out;
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    System.setOut(new PrintStream(baos));
+    compileWithR8(ImmutableList.of(A.class), proguardConfig);
+    String output = new String(baos.toByteArray(), Charset.defaultCharset());
+    System.setOut(stdout);
+    String expected = String.join("\n", ImmutableList.of(
+        "com.android.tools.r8.shaking.whyareyoukeeping.A",
+        "|- is live because referenced in keep rule:",
+        "|    -keep  class com.android.tools.r8.shaking.whyareyoukeeping.A {",
+        "|      *;",
+        "|    };",
+        ""));
+    assertEquals(expected, output);
+  }
+}