Version 2.1.57

Cherry-pick: Close stream of input source when dumping
CL: https://r8-review.googlesource.com/52560

Cherry-pick: Move synchronization of class initializer from DexClass to MethodColl
CL: https://r8-review.googlesource.com/52544

Cherry-pick: Add reproduction of removed fields in kotlin.Metadata
CL: https://r8-review.googlesource.com/52666

Cherry-pick: Only emit kotlin metadata values for non-pruned
annotation members
CL: https://r8-review.googlesource.com/52667

Bug: 160901582
Bug: 159194018
Bug: 161230424
Bug: 162900580
Bug: 152476580
Change-Id: I3e506acaba9333ed6bd31d7229f5982bab215696
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 4037c85..f1e1b89 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "2.1.56";
+  public static final String LABEL = "2.1.57";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index be8c6f1..1c9b40c 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -532,8 +532,10 @@
     return false;
   }
 
-  public synchronized DexEncodedMethod getClassInitializer() {
-    return methodCollection.getClassInitializer();
+  public DexEncodedMethod getClassInitializer() {
+    DexEncodedMethod classInitializer = methodCollection.getClassInitializer();
+    assert classInitializer != DexEncodedMethod.SENTINEL;
+    return classInitializer;
   }
 
   public Origin getOrigin() {
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index cf25051..adb1dcc 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -119,7 +119,11 @@
   public static final DexEncodedMethod[] EMPTY_ARRAY = {};
   public static final DexEncodedMethod SENTINEL =
       new DexEncodedMethod(
-          null, null, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null);
+          null,
+          MethodAccessFlags.fromDexAccessFlags(0),
+          DexAnnotationSet.empty(),
+          ParameterAnnotationsList.empty(),
+          null);
   public static final Int2ReferenceMap<DebugLocalInfo> NO_PARAMETER_INFO =
       new Int2ReferenceArrayMap<>(0);
 
@@ -246,6 +250,7 @@
     this.code = code;
     this.classFileVersion = classFileVersion;
     this.d8R8Synthesized = d8R8Synthesized;
+    assert accessFlags != null;
     assert code == null || !shouldNotHaveCode();
     assert parameterAnnotationsList != null;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/MethodCollection.java b/src/main/java/com/android/tools/r8/graph/MethodCollection.java
index c93d366..b1a8f8e 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodCollection.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodCollection.java
@@ -178,7 +178,7 @@
     cachedClassInitializer = DexEncodedMethod.SENTINEL;
   }
 
-  public DexEncodedMethod getClassInitializer() {
+  public synchronized DexEncodedMethod getClassInitializer() {
     if (cachedClassInitializer == DexEncodedMethod.SENTINEL) {
       cachedClassInitializer = null;
       for (DexEncodedMethod directMethod : directMethods()) {
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
index 2171a00..281950c 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
@@ -188,8 +188,8 @@
     return v.asDexValueString().getValue().toString();
   }
 
-  private static class MetadataError extends RuntimeException {
-    MetadataError(String cause) {
+  public static class MetadataError extends RuntimeException {
+    private MetadataError(String cause) {
       super(cause);
     }
   }
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
index d709ea4..5e11d43 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
@@ -9,8 +9,10 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationElement;
+import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedAnnotation;
 import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexValue;
 import com.android.tools.r8.graph.DexValue.DexValueArray;
 import com.android.tools.r8.graph.DexValue.DexValueInt;
@@ -25,6 +27,36 @@
 
 public class KotlinMetadataRewriter {
 
+  private static final class WriteMetadataFieldInfo {
+    final boolean writeKind;
+    final boolean writeMetadataVersion;
+    final boolean writeByteCodeVersion;
+    final boolean writeData1;
+    final boolean writeData2;
+    final boolean writeExtraString;
+    final boolean writePackageName;
+    final boolean writeExtraInt;
+
+    public WriteMetadataFieldInfo(
+        boolean writeKind,
+        boolean writeMetadataVersion,
+        boolean writeByteCodeVersion,
+        boolean writeData1,
+        boolean writeData2,
+        boolean writeExtraString,
+        boolean writePackageName,
+        boolean writeExtraInt) {
+      this.writeKind = writeKind;
+      this.writeMetadataVersion = writeMetadataVersion;
+      this.writeByteCodeVersion = writeByteCodeVersion;
+      this.writeData1 = writeData1;
+      this.writeData2 = writeData2;
+      this.writeExtraString = writeExtraString;
+      this.writePackageName = writePackageName;
+      this.writeExtraInt = writeExtraInt;
+    }
+  }
+
   private final AppView<?> appView;
   private final NamingLens lens;
   private final DexItemFactory factory;
@@ -42,6 +74,18 @@
   }
 
   public void run(ExecutorService executorService) throws ExecutionException {
+    final DexClass kotlinMetadata =
+        appView.definitionFor(appView.dexItemFactory().kotlinMetadataType);
+    final WriteMetadataFieldInfo writeMetadataFieldInfo =
+        new WriteMetadataFieldInfo(
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.kind),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.metadataVersion),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.bytecodeVersion),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.data1),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.data2),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.extraString),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.packageName),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.extraInt));
     ThreadUtils.processItems(
         appView.appInfo().classes(),
         clazz -> {
@@ -66,7 +110,8 @@
           try {
             KotlinClassHeader kotlinClassHeader = kotlinInfo.rewrite(clazz, appView, lens);
             DexAnnotation newMeta =
-                createKotlinMetadataAnnotation(kotlinClassHeader, kotlinInfo.getPackageName());
+                createKotlinMetadataAnnotation(
+                    kotlinClassHeader, kotlinInfo.getPackageName(), writeMetadataFieldInfo);
             clazz.setAnnotations(
                 clazz.annotations().rewrite(anno -> anno == oldMeta ? newMeta : anno));
           } catch (Throwable t) {
@@ -79,33 +124,54 @@
         executorService);
   }
 
+  private boolean kotlinMetadataFieldExists(
+      DexClass kotlinMetadata, AppView<?> appView, DexString fieldName) {
+    if (!appView.appInfo().hasLiveness()) {
+      return true;
+    }
+    if (kotlinMetadata == null || kotlinMetadata.isNotProgramClass()) {
+      return true;
+    }
+    return kotlinMetadata.methods(method -> method.method.name == fieldName).iterator().hasNext();
+  }
+
   private DexAnnotation createKotlinMetadataAnnotation(
-      KotlinClassHeader header, String packageName) {
+      KotlinClassHeader header, String packageName, WriteMetadataFieldInfo writeMetadataFieldInfo) {
     List<DexAnnotationElement> elements = new ArrayList<>();
-    elements.add(
-        new DexAnnotationElement(
-            kotlin.metadata.metadataVersion, createIntArray(header.getMetadataVersion())));
-    elements.add(
-        new DexAnnotationElement(
-            kotlin.metadata.bytecodeVersion, createIntArray(header.getBytecodeVersion())));
-    elements.add(
-        new DexAnnotationElement(kotlin.metadata.kind, DexValueInt.create(header.getKind())));
-    elements.add(
-        new DexAnnotationElement(kotlin.metadata.data1, createStringArray(header.getData1())));
-    elements.add(
-        new DexAnnotationElement(kotlin.metadata.data2, createStringArray(header.getData2())));
-    if (packageName != null && !packageName.isEmpty()) {
+    if (writeMetadataFieldInfo.writeMetadataVersion) {
+      elements.add(
+          new DexAnnotationElement(
+              kotlin.metadata.metadataVersion, createIntArray(header.getMetadataVersion())));
+    }
+    if (writeMetadataFieldInfo.writeByteCodeVersion) {
+      elements.add(
+          new DexAnnotationElement(
+              kotlin.metadata.bytecodeVersion, createIntArray(header.getBytecodeVersion())));
+    }
+    if (writeMetadataFieldInfo.writeKind) {
+      elements.add(
+          new DexAnnotationElement(kotlin.metadata.kind, DexValueInt.create(header.getKind())));
+    }
+    if (writeMetadataFieldInfo.writeData1) {
+      elements.add(
+          new DexAnnotationElement(kotlin.metadata.data1, createStringArray(header.getData1())));
+    }
+    if (writeMetadataFieldInfo.writeData2) {
+      elements.add(
+          new DexAnnotationElement(kotlin.metadata.data2, createStringArray(header.getData2())));
+    }
+    if (writeMetadataFieldInfo.writePackageName && packageName != null && !packageName.isEmpty()) {
       elements.add(
           new DexAnnotationElement(
               kotlin.metadata.packageName, new DexValueString(factory.createString(packageName))));
     }
-    if (!header.getExtraString().isEmpty()) {
+    if (writeMetadataFieldInfo.writeExtraString && !header.getExtraString().isEmpty()) {
       elements.add(
           new DexAnnotationElement(
               kotlin.metadata.extraString,
               new DexValueString(factory.createString(header.getExtraString()))));
     }
-    if (header.getExtraInt() != 0) {
+    if (writeMetadataFieldInfo.writeExtraInt && header.getExtraInt() != 0) {
       elements.add(
           new DexAnnotationElement(
               kotlin.metadata.extraInt, DexValueInt.create(header.getExtraInt())));
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApp.java b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
index 8599b02..faebc96 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApp.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
@@ -640,7 +640,7 @@
       ZipOutputStream dexArchiveOutputStream,
       ProgramResource programResource)
       throws ResourceException, IOException {
-    byte[] bytes = ByteStreams.toByteArray(programResource.getByteStream());
+    byte[] bytes = StreamUtils.StreamToByteArrayClose(programResource.getByteStream());
     if (programResource.getKind() == Kind.CF) {
       Set<String> classDescriptors = programResource.getClassDescriptors();
       String classDescriptor =
diff --git a/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java b/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
index 2d56233..0465bc5 100644
--- a/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
@@ -12,6 +12,7 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.conversion.CallGraph.Node;
@@ -50,7 +51,11 @@
         new ProgramMethod(
             clazz,
             new DexEncodedMethod(
-                signature, null, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null));
+                signature,
+                MethodAccessFlags.fromDexAccessFlags(0),
+                DexAnnotationSet.empty(),
+                ParameterAnnotationsList.empty(),
+                null));
     return new Node(method);
   }
 
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java
new file mode 100644
index 0000000..77134d8
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java
@@ -0,0 +1,85 @@
+// Copyright (c) 2020, 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.kotlin.metadata;
+
+import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
+import com.android.tools.r8.kotlin.metadata.metadata_pruned_fields.Main;
+import com.android.tools.r8.shaking.ProguardKeepAttributes;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/** This is a reproduction of b/161230424. */
+@RunWith(Parameterized.class)
+public class MetadataPrunedFieldsTest extends KotlinMetadataTestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0} target: {1}")
+  public static Collection<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withAllRuntimesAndApiLevels().build(), KotlinTargetVersion.values());
+  }
+
+  public MetadataPrunedFieldsTest(TestParameters parameters, KotlinTargetVersion targetVersion) {
+    super(targetVersion);
+    this.parameters = parameters;
+  }
+
+  private static Map<KotlinTargetVersion, Path> libJars = new HashMap<>();
+
+  @BeforeClass
+  public static void createLibJar() throws Exception {
+    String baseLibFolder = PKG_PREFIX + "/metadata_pruned_fields";
+    for (KotlinTargetVersion targetVersion : KotlinTargetVersion.values()) {
+      Path baseLibJar =
+          kotlinc(KOTLINC, targetVersion)
+              .addSourceFiles(getKotlinFileInTest(baseLibFolder, "Methods"))
+              .compile();
+      libJars.put(targetVersion, baseLibJar);
+    }
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramFiles(ToolHelper.getKotlinStdlibJar())
+        .addProgramFiles(libJars.get(targetVersion))
+        .addProgramClassFileData(Main.dump())
+        .addKeepRules("-keep class " + PKG + ".metadata_pruned_fields.MethodsKt { *; }")
+        .addKeepRules("-keep class kotlin.Metadata { *** pn(); }")
+        .addKeepMainRule(Main.class)
+        .allowDiagnosticWarningMessages()
+        .setMinApi(parameters.getApiLevel())
+        .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
+        .compile()
+        .inspect(
+            codeInspector -> {
+              final ClassSubject clazz = codeInspector.clazz("kotlin.Metadata");
+              assertThat(clazz, isPresent());
+              assertThat(clazz.uniqueMethodWithName("pn"), isPresent());
+              assertThat(clazz.uniqueMethodWithName("d1"), not(isPresent()));
+              assertThat(clazz.uniqueMethodWithName("d2"), not(isPresent()));
+              assertThat(clazz.uniqueMethodWithName("bv"), not(isPresent()));
+            })
+        .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("", "Hello World!");
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
index f474cf1..fd70455 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
@@ -101,7 +101,7 @@
         .addProgramFiles(inputJarMap.get(targetVersion))
         .addKeepRules(OBFUSCATE_RENAMED, KEEP_KEPT)
         .addKeepRules("-keep class **.Anno")
-        .addKeepRules("-keep class kotlin.Metadata")
+        .addKeepKotlinMetadata()
         .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
         .allowDiagnosticWarningMessages()
         .compile()
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java
index 295f26a..3986b38 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java
@@ -4,17 +4,15 @@
 
 package com.android.tools.r8.kotlin.metadata;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
 
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
+import com.android.tools.r8.kotlin.KotlinClassMetadataReader.MetadataError;
 import com.android.tools.r8.shaking.ProguardKeepAttributes;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
 import java.util.Collection;
@@ -51,55 +49,19 @@
   }
 
   @Test
-  public void testR8KeepPartial() throws Exception {
-    // This test is a bit weird, since it shows that we can remove params from the kotlin.Metadata
-    // class, but still be able to fully read the kotlin.Metadata.
-    testForR8(parameters.getBackend())
-        .addProgramFiles(ToolHelper.getKotlinStdlibJar())
-        .setMinApi(parameters.getApiLevel())
-        .addKeepRules("-keep class kotlin.Metadata { *** d1(); }")
-        .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
-        .compile()
-        .inspect(
-            inspector -> {
-              inspect(inspector);
-              ClassSubject kotlinMetadataClass = inspector.clazz("kotlin.Metadata");
-              assertThat(kotlinMetadataClass, isPresent());
-              assertEquals(1, kotlinMetadataClass.allMethods().size());
-              assertNotNull(kotlinMetadataClass.getKmClass().getName());
-            });
-  }
-
-  @Test
-  public void testR8KeepPartialCooking() throws Exception {
-    // This test is a bit weird, since it shows that we can remove params from the kotlin.Metadata
-    // class, but still be able to fully read the kotlin.Metadata externally.
-    testForR8(parameters.getBackend())
-        .addProgramFiles(ToolHelper.getKotlinStdlibJar())
-        .setMinApi(parameters.getApiLevel())
-        .addKeepRules("-keep class kotlin.Metadata { *** d1(); }")
-        .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
-        .compile()
-        .inspect(
-            inspector -> {
-              inspect(inspector);
-              ClassSubject kotlinMetadataClass = inspector.clazz("kotlin.Metadata");
-              assertThat(kotlinMetadataClass, isPresent());
-              assertEquals(1, kotlinMetadataClass.allMethods().size());
-              assertNotNull(kotlinMetadataClass.getKmClass().getName());
-            });
-  }
-
-  @Test
   public void testR8KeepIf() throws Exception {
     testForR8(parameters.getBackend())
         .addProgramFiles(ToolHelper.getKotlinStdlibJar())
         .setMinApi(parameters.getApiLevel())
         .addKeepRules("-keep class kotlin.io.** { *; }")
-        .addKeepRules("-if class * { *** $VALUES; }", "-keep class kotlin.Metadata { *; }")
+        .addKeepRules("-if class *", "-keep class kotlin.Metadata { *; }")
         .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
         .compile()
-        .inspect(this::inspect);
+        .inspect(
+            codeInspector -> {
+              // TODO(b/162900580): This should be kept or the test refined.
+              assertThrows(MetadataError.class, () -> inspect(codeInspector));
+            });
   }
 
   private void inspect(CodeInspector inspector) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Main.java b/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Main.java
new file mode 100644
index 0000000..10ebf6b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Main.java
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, 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.kotlin.metadata.metadata_pruned_fields;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+public class Main implements Opcodes {
+
+  // The dump is generated from the code below, which cannot compile because of a missing
+  // reference to MethodsKt.
+  //
+  // public static void main(String[] args) {
+  //   final kotlin.Metadata annotation = MethodsKt.class.getAnnotation(kotlin.Metadata.class);
+  //   System.out.println(annotation.pn());
+  //   MethodsKt.staticMethod();
+  // }
+
+  public static byte[] dump() {
+
+    ClassWriter classWriter = new ClassWriter(0);
+    MethodVisitor methodVisitor;
+
+    classWriter.visit(
+        V1_8,
+        ACC_PUBLIC | ACC_SUPER,
+        "com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Main",
+        null,
+        "java/lang/Object",
+        new String[] {});
+
+    {
+      methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+      methodVisitor.visitCode();
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(1, 1);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor =
+          classWriter.visitMethod(
+              ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+      methodVisitor.visitCode();
+      methodVisitor.visitLdcInsn(
+          Type.getType("Lcom/android/tools/r8/kotlin/metadata/metadata_pruned_fields/MethodsKt;"));
+      methodVisitor.visitLdcInsn(Type.getType("Lkotlin/Metadata;"));
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL,
+          "java/lang/Class",
+          "getAnnotation",
+          "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;",
+          false);
+      methodVisitor.visitTypeInsn(CHECKCAST, "kotlin/Metadata");
+      methodVisitor.visitVarInsn(ASTORE, 1);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitVarInsn(ALOAD, 1);
+      methodVisitor.visitMethodInsn(
+          INVOKEINTERFACE, "kotlin/Metadata", "pn", "()Ljava/lang/String;", true);
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/MethodsKt",
+          "staticMethod",
+          "()V",
+          false);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 2);
+      methodVisitor.visitEnd();
+    }
+    classWriter.visitEnd();
+
+    return classWriter.toByteArray();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Methods.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Methods.kt
new file mode 100644
index 0000000..5f67164
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Methods.kt
@@ -0,0 +1,9 @@
+// Copyright (c) 2020, 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.kotlin.metadata.metadata_pruned_fields
+
+fun staticMethod() {
+  println("Hello World!")
+}
\ No newline at end of file