Add tests about Kotlin properties that are no longer property after shrinking.

Bug: 70169921
Change-Id: I8a4503338a734c6d5de93bbe43485373152d5bdc
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRenameInPropertyTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRenameInPropertyTest.java
new file mode 100644
index 0000000..c671ea5
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRenameInPropertyTest.java
@@ -0,0 +1,138 @@
+// 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 com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.R8TestCompileResult;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
+import com.android.tools.r8.shaking.ProguardKeepAttributes;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.KmClassSubject;
+import java.nio.file.Path;
+import java.util.Collection;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class MetadataRenameInPropertyTest extends KotlinMetadataTestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0} target: {1}")
+  public static Collection<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withCfRuntimes().build(), KotlinTargetVersion.values());
+  }
+
+  public MetadataRenameInPropertyTest(
+      TestParameters parameters, KotlinTargetVersion targetVersion) {
+    super(targetVersion);
+    this.parameters = parameters;
+  }
+
+  private static Path propertyTypeLibJar;
+
+  @BeforeClass
+  public static void createLibJar() throws Exception {
+    String propertyTypeLibFolder = PKG_PREFIX + "/fragile_property_lib";
+    propertyTypeLibJar =
+        kotlinc(KOTLINC, KotlinTargetVersion.JAVA_8)
+            .addSourceFiles(getKotlinFileInTest(propertyTypeLibFolder, "lib"))
+            .compile();
+  }
+
+  @Test
+  public void testMetadataInProperty_getterOnly() throws Exception {
+    R8TestCompileResult compileResult =
+        testForR8(parameters.getBackend())
+            .addProgramFiles(propertyTypeLibJar)
+            // Keep property getters
+            .addKeepRules("-keep class **.Person { <init>(...); }")
+            .addKeepRules("-keepclassmembers class **.Person { *** get*(); }")
+            .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
+            .addOptionsModification(InternalOptions::enableKotlinMetadataRewriting)
+            .compile();
+    String pkg = getClass().getPackage().getName();
+    final String personClassName = pkg + ".fragile_property_lib.Person";
+    compileResult.inspect(inspector -> {
+      ClassSubject person = inspector.clazz(personClassName);
+      assertThat(person, isPresent());
+      assertThat(person, not(isRenamed()));
+      // API entry is kept, hence the presence of Metadata.
+      KmClassSubject kmClass = person.getKmClass();
+      assertThat(kmClass, isPresent());
+      // TODO(b/70169921): test property details.
+    });
+
+    Path libJar = compileResult.writeToZip();
+
+    String appFolder = PKG_PREFIX + "/fragile_property_only_getter";
+    Path output =
+        kotlinc(parameters.getRuntime().asCf(), KOTLINC, KotlinTargetVersion.JAVA_8)
+            .addClasspathFiles(libJar)
+            .addSourceFiles(getKotlinFileInTest(appFolder, "getter_user"))
+            .setOutputPath(temp.newFolder().toPath())
+            .compile();
+
+    testForJvm()
+        .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(), libJar)
+        .addClasspath(output)
+        .run(parameters.getRuntime(), pkg + ".fragile_property_only_getter.Getter_userKt")
+        .assertSuccessWithOutputLines("true", "false", "Hey");
+  }
+
+  @Test
+  public void testMetadataInProperty_setterOnly() throws Exception {
+    R8TestCompileResult compileResult =
+        testForR8(parameters.getBackend())
+            .addProgramFiles(propertyTypeLibJar)
+            // Keep property setters (and users)
+            .addKeepRules("-keep class **.Person { <init>(...); }")
+            .addKeepRules("-keepclassmembers class **.Person { void set*(...); }")
+            .addKeepRules("-keepclassmembers class **.Person { void aging(); }")
+            .addKeepRules("-keepclassmembers class **.Person { void change*(...); }")
+            // Keep LibKt extension methods
+            .addKeepRules("-keep class **.LibKt { <methods>; }")
+            .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
+            .addOptionsModification(InternalOptions::enableKotlinMetadataRewriting)
+            .compile();
+    String pkg = getClass().getPackage().getName();
+    final String personClassName = pkg + ".fragile_property_lib.Person";
+    compileResult.inspect(inspector -> {
+      ClassSubject person = inspector.clazz(personClassName);
+      assertThat(person, isPresent());
+      assertThat(person, not(isRenamed()));
+      // API entry is kept, hence the presence of Metadata.
+      KmClassSubject kmClass = person.getKmClass();
+      assertThat(kmClass, isPresent());
+      // TODO(b/70169921): test property details.
+    });
+
+    Path libJar = compileResult.writeToZip();
+
+    String appFolder = PKG_PREFIX + "/fragile_property_only_setter";
+    Path output =
+        kotlinc(parameters.getRuntime().asCf(), KOTLINC, KotlinTargetVersion.JAVA_8)
+            .addClasspathFiles(libJar)
+            .addSourceFiles(getKotlinFileInTest(appFolder, "setter_user"))
+            .setOutputPath(temp.newFolder().toPath())
+            .compile();
+
+    testForJvm()
+        .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(), libJar)
+        .addClasspath(output)
+        .run(parameters.getRuntime(), pkg + ".fragile_property_only_setter.Setter_userKt")
+        .assertSuccessWithOutputLines();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/fragile_property_lib/lib.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/fragile_property_lib/lib.kt
new file mode 100644
index 0000000..bb88f97
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/fragile_property_lib/lib.kt
@@ -0,0 +1,33 @@
+// 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.fragile_property_lib
+
+class Person(var name: String) {
+
+  val firstName: String
+    get() = name.split(" ").dropLast(1).joinToString(" ")
+
+  val familyName: String
+    get() = name.split(" ").last()
+
+  constructor(name: String, age: Int) : this(name) {
+    this.age = age
+  }
+
+  var age: Int = 0
+
+  fun aging() {
+    age++
+  }
+
+  val canDrink: Boolean
+    get() = age >= 21
+
+  @set:JvmName("changeMaritalStatus")
+  var married: Boolean = false
+}
+
+fun Person.changeAgeLegally(newAge: Int) {
+  this.age = newAge
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/fragile_property_only_getter/getter_user.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/fragile_property_only_getter/getter_user.kt
new file mode 100644
index 0000000..b85bd2e
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/fragile_property_only_getter/getter_user.kt
@@ -0,0 +1,15 @@
+// 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.fragile_property_only_getter
+
+import com.android.tools.r8.kotlin.metadata.fragile_property_lib.Person
+
+fun main() {
+  val x = Person("John Doe", 42)
+  val y = Person("Hey Jude", 48)
+
+  println(x.canDrink)
+  println(x.married)
+  println(y.firstName)
+}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/fragile_property_only_setter/setter_user.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/fragile_property_only_setter/setter_user.kt
new file mode 100644
index 0000000..20fbe33
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/fragile_property_only_setter/setter_user.kt
@@ -0,0 +1,15 @@
+// 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.fragile_property_only_setter
+
+import com.android.tools.r8.kotlin.metadata.fragile_property_lib.Person
+import com.android.tools.r8.kotlin.metadata.fragile_property_lib.changeAgeLegally
+
+fun main() {
+  val x = Person("John Doe", 42)
+  val y = Person("Hey Jude", 48)
+
+  x.aging()
+  y.changeAgeLegally(42)
+}