[keepanno] @UsesReflectiontoAccessField kotlin-reflect properties test

Bug: b/392865072

Change-Id: I4c5ffa9401a1d9616d67e2bc535a02544ed5972e
diff --git a/src/test/java/com/android/tools/r8/keepanno/androidx/KeepUsesReflectionToAccessFieldTest.java b/src/test/java/com/android/tools/r8/keepanno/androidx/KeepUsesReflectionToAccessFieldTest.java
index d5ce9e4..5ddca5d 100644
--- a/src/test/java/com/android/tools/r8/keepanno/androidx/KeepUsesReflectionToAccessFieldTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/androidx/KeepUsesReflectionToAccessFieldTest.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8.keepanno.androidx;
 
 import static com.android.tools.r8.ToolHelper.getFilesInTestFolderRelativeToClass;
+import static org.hamcrest.CoreMatchers.containsString;
 
 import androidx.annotation.keep.UsesReflectionToAccessField;
 import com.android.tools.r8.ToolHelper.DexVm.Version;
@@ -18,6 +19,8 @@
 import java.nio.file.Path;
 import java.util.Collection;
 import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -43,8 +46,14 @@
 
   private static Collection<Path> getKotlinSources() {
     try {
-      return getFilesInTestFolderRelativeToClass(
-          KeepUsesReflectionToAccessFieldTest.class, "kt", "Fields.kt", "FieldsKeptClass.kt");
+      return Stream.concat(
+              getFilesInTestFolderRelativeToClass(
+                  KeepUsesReflectionToAccessFieldTest.class, "kt", "Fields.kt")
+                  .stream(),
+              getFilesInTestFolderRelativeToClass(
+                  KeepUsesReflectionToAccessFieldTest.class, "kt", "FieldsPropertyAccess.kt")
+                  .stream())
+          .collect(Collectors.toList());
     } catch (IOException e) {
       throw new RuntimeException(e);
     }
@@ -269,6 +278,42 @@
         StringUtils.lines("3"));
   }
 
+  @Test
+  public void testPropertyAccessKotlin() throws Exception {
+    testExtractedRulesAndRunKotlin(
+        compilationResults,
+        (classReference, classFileBytes) ->
+            setAnnotationOnMethod(
+                classReference,
+                classFileBytes,
+                Reference.classFromTypeName(
+                    "com.android.tools.r8.keepanno.androidx.kt.FieldsPropertyAccess"),
+                MethodPredicate.onName("foo"),
+                builder ->
+                    buildUsesReflectionToAccessField(
+                        builder,
+                        Type.getType(
+                            DescriptorUtils.javaTypeToDescriptor(
+                                "com.android.tools.r8.keepanno.androidx.kt.FieldsPropertyAccessKeptClass")),
+                        "x",
+                        int.class)),
+        "com.android.tools.r8.keepanno.androidx.kt.FieldsPropertyAccessKt",
+        getExpectedRulesKotlin(
+            "com.android.tools.r8.keepanno.androidx.kt.FieldsPropertyAccess",
+            "{ void foo(); }",
+            "com.android.tools.r8.keepanno.androidx.kt.FieldsPropertyAccessKeptClass",
+            "{ int x; }"),
+        // TODO(b/392865072): Not sure why this succeeds on DEX even though the getter getX has
+        //  been removed.
+        parameters.getBackend().isDex()
+            ? r -> r.assertSuccessWithOutput(StringUtils.lines("1"))
+            : r ->
+                r.assertFailureWithErrorThatMatches(
+                    containsString(
+                        "Property 'x' (JVM signature: getX()I) not resolved in class"
+                            + " com.android.tools.r8.keepanno.androidx.kt")));
+  }
+
   // Test class without annotation to be used by multiple tests inserting annotations using a
   // transformer.
   static class ClassWithAnnotation {
diff --git a/src/test/java/com/android/tools/r8/keepanno/androidx/kt/FieldsPropertyAccess.kt b/src/test/java/com/android/tools/r8/keepanno/androidx/kt/FieldsPropertyAccess.kt
new file mode 100644
index 0000000..69a27b4
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/keepanno/androidx/kt/FieldsPropertyAccess.kt
@@ -0,0 +1,27 @@
+// Copyright (c) 2025, 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.keepanno.androidx.kt
+
+import kotlin.reflect.KProperty
+
+class FieldsPropertyAccess {
+  fun foo() {
+    val x: KProperty<*> = FieldsPropertyAccessKeptClass::x
+    val y: KProperty<*> = FieldsPropertyAccessKeptClass::y
+    val s: KProperty<*> = FieldsPropertyAccessKeptClass::s
+    println(x.call(FieldsPropertyAccessKeptClass()))
+  }
+}
+
+class FieldsPropertyAccessKeptClass {
+  var x: Int = 1
+
+  var y: Long = 2
+
+  var s: String = "3"
+}
+
+fun main() {
+  FieldsPropertyAccess().foo()
+}