Extend metadata prune test with non-pinned functions and properties

Bug: 186508801
Change-Id: I333484a6c0d9908068bccfeb9909a245fd7657db
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePrunedObjectsTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePrunedObjectsTest.java
index 2de9622..638d118 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePrunedObjectsTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePrunedObjectsTest.java
@@ -26,13 +26,17 @@
 @RunWith(Parameterized.class)
 public class MetadataRewritePrunedObjectsTest extends KotlinMetadataTestBase {
 
-  private final String EXPECTED = StringUtils.lines("42");
+  private final String EXPECTED = StringUtils.lines("42", "0", "Goodbye World");
   private static final String PKG_LIB = PKG + ".pruned_lib";
   private static final String PKG_APP = PKG + ".pruned_app";
 
   private static final KotlinCompileMemoizer libJars =
       getCompileMemoizer(
-          getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_LIB), "lib"));
+              getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_LIB), "lib"))
+          .configure(
+              kotlinCompilerTool -> {
+                kotlinCompilerTool.addClasspathFiles(ToolHelper.getClassPathForTests());
+              });
   private final TestParameters parameters;
 
   @Parameterized.Parameters(name = "{0}, {1}")
@@ -70,8 +74,12 @@
     Path libJar =
         testForR8(parameters.getBackend())
             .addProgramFiles(libJars.getForConfiguration(kotlinc, targetVersion))
-            .addClasspathFiles(ToolHelper.getKotlinStdlibJar(kotlinc))
-            .addKeepRules("-keep class " + PKG_LIB + ".Sub { <init>(); *** kept(); }")
+            .enableInliningAnnotations()
+            .addClasspathFiles(
+                ToolHelper.getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinAnnotationJar(kotlinc))
+            .addKeepRules(
+                "-keep class " + PKG_LIB + ".Sub { <init>(); *** kept(); *** keptProperty; }")
+            .addKeepClassAndMembersRules(PKG_LIB + ".SubUser")
             .addKeepRuntimeVisibleAnnotations()
             .noMinification()
             .compile()
@@ -98,6 +106,15 @@
     KmClassSubject kmClass = sub.getKmClass();
     assertThat(kmClass, isPresent());
     assertEquals(0, kmClass.getSuperTypes().size());
+    // Ensure that we do not prune the constructors.
+    assertEquals(1, kmClass.getConstructors().size());
+    // Assert that we have removed the metadata for a function that is removed.
     assertThat(kmClass.kmFunctionWithUniqueName("notKept"), not(isPresent()));
+    // TODO(b/186508801): This should be removed.
+    assertThat(kmClass.kmFunctionWithUniqueName("keptWithoutPinning"), isPresent());
+    // Check that we have not pruned the property information for a kept field.
+    assertThat(kmClass.kmPropertyWithUniqueName("keptProperty"), isPresent());
+    // TODO(b/186508801): This should be removed.
+    assertThat(kmClass.kmPropertyWithUniqueName("notExposedProperty"), isPresent());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/pruned_app/main.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/pruned_app/main.kt
index fb35a60..1ba0b77 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/pruned_app/main.kt
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/pruned_app/main.kt
@@ -5,7 +5,10 @@
 package com.android.tools.r8.kotlin.metadata.pruned_app
 
 import com.android.tools.r8.kotlin.metadata.pruned_lib.Sub
+import com.android.tools.r8.kotlin.metadata.pruned_lib.SubUser
 
 fun main() {
-  println(Sub().kept())
+  val sub = Sub()
+  println(sub.kept())
+  SubUser().use(sub)
 }
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/pruned_lib/lib.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/pruned_lib/lib.kt
index 3ceaa4d..a7672fd 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/pruned_lib/lib.kt
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/pruned_lib/lib.kt
@@ -4,17 +4,42 @@
 
 package com.android.tools.r8.kotlin.metadata.pruned_lib
 
-// The Base class will be removed during
+import com.android.tools.r8.NeverInline
+
+// The Base class will be removed during compilation
 open class Base
 
 class Sub : Base() {
 
+  var notExposedProperty : Int = 42
+  var keptProperty : String = "Hello World";
+
   fun notKept() : Boolean {
     return true
   }
 
+  @NeverInline
+  fun keptWithoutPinning() : Int {
+    if (System.currentTimeMillis() == 0L) {
+      return 41;
+    }
+    return 42;
+  }
+
   fun kept() : Int {
-    return 42
+    if (System.currentTimeMillis() > 0) {
+      notExposedProperty = 0
+      keptProperty = "Goodbye World"
+    }
+    return keptWithoutPinning()
   }
 }
 
+class SubUser {
+
+  @NeverInline
+  fun use(s : Sub) {
+    println(s.notExposedProperty)
+    println(s.keptProperty)
+  }
+}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentKmClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentKmClassSubject.java
index a58d5ee..d87e74e 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentKmClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentKmClassSubject.java
@@ -21,6 +21,11 @@
   }
 
   @Override
+  public List<KmConstructorSubject> getConstructors() {
+    return null;
+  }
+
+  @Override
   public boolean isPresent() {
     return false;
   }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmClassSubject.java
index 51d7152..cc9bfd0 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmClassSubject.java
@@ -37,6 +37,13 @@
   }
 
   @Override
+  public List<KmConstructorSubject> getConstructors() {
+    return kmClass.getConstructors().stream()
+        .map(constructor -> new FoundKmConstructorSubject(codeInspector, constructor))
+        .collect(Collectors.toList());
+  }
+
+  @Override
   public CodeInspector codeInspector() {
     return codeInspector;
   }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmConstructorSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmConstructorSubject.java
new file mode 100644
index 0000000..19a783f
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmConstructorSubject.java
@@ -0,0 +1,53 @@
+// Copyright (c) 2021, 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.utils.codeinspector;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import kotlinx.metadata.KmConstructor;
+import kotlinx.metadata.jvm.JvmExtensionsKt;
+import kotlinx.metadata.jvm.JvmMethodSignature;
+
+public class FoundKmConstructorSubject extends KmConstructorSubject {
+
+  private final CodeInspector codeInspector;
+  private final KmConstructor kmConstructor;
+
+  FoundKmConstructorSubject(CodeInspector codeInspector, KmConstructor kmConstructor) {
+    this.codeInspector = codeInspector;
+    this.kmConstructor = kmConstructor;
+  }
+
+  @Override
+  public JvmMethodSignature signature() {
+    JvmExtensionsKt.getSignature(this.kmConstructor);
+    return null;
+  }
+
+  @Override
+  public List<KmValueParameterSubject> valueParameters() {
+    return kmConstructor.getValueParameters().stream()
+        .map(kmValueParameter -> new KmValueParameterSubject(codeInspector, kmValueParameter))
+        .collect(Collectors.toList());
+  }
+
+  @Override
+  public boolean isPresent() {
+    return true;
+  }
+
+  @Override
+  public boolean isRenamed() {
+    // TODO(b/151194869): need to know the corresponding DexEncodedMethod.
+    return false;
+  }
+
+  @Override
+  public boolean isSynthetic() {
+    // TODO(b/151194785): This should return `true` conditionally if we start synthesizing @Metadata
+    //   from scratch.
+    return false;
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/KmClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/KmClassSubject.java
index 753f02a..9d776d3 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/KmClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/KmClassSubject.java
@@ -12,6 +12,8 @@
 
   public abstract DexClass getDexClass();
 
+  public abstract List<KmConstructorSubject> getConstructors();
+
   public abstract List<String> getSuperTypeDescriptors();
 
   public abstract List<ClassSubject> getSuperTypes();
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/KmConstructorSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/KmConstructorSubject.java
new file mode 100644
index 0000000..7a2e468
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/KmConstructorSubject.java
@@ -0,0 +1,14 @@
+// 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.utils.codeinspector;
+
+import java.util.List;
+import kotlinx.metadata.jvm.JvmMethodSignature;
+
+public abstract class KmConstructorSubject extends Subject {
+
+  public abstract JvmMethodSignature signature();
+
+  public abstract List<KmValueParameterSubject> valueParameters();
+}