Towards synthesizing Kotlin @Metadata: nestedClass in KmClass.

Bug: 70169921
Change-Id: I9a5d1b1bc4f5e0c3bf57993deab60edcb80a96b0
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClass.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClass.java
index 9ac3a82..48f29c2 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClass.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClass.java
@@ -14,7 +14,9 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.List;
@@ -76,7 +78,28 @@
       superTypes.add(toKmType(addKotlinPrefix("Any;")));
     }
 
-    // TODO(b/70169921): downward hierarchy is harmless. Move above member-rewriting flag.
+    // Rewriting downward hierarchies: nested.
+    List<String> nestedClasses = kmClass.getNestedClasses();
+    nestedClasses.clear();
+    for (InnerClassAttribute innerClassAttribute : clazz.getInnerClasses()) {
+      DexString renamedInnerName = lens.lookupInnerName(innerClassAttribute, appView.options());
+      if (renamedInnerName != null) {
+        nestedClasses.add(renamedInnerName.toString());
+      }
+    }
+
+    // Rewriting downward hierarchies: sealed.
+    List<String> sealedSubclasses = kmClass.getSealedSubclasses();
+    sealedSubclasses.clear();
+    if (IS_SEALED.invoke(kmClass.getFlags())) {
+      for (DexType subtype : appView.appInfo().allImmediateSubtypes(clazz.type)) {
+        String classifier = toRenamedClassifier(subtype, appView, lens);
+        if (classifier != null) {
+          sealedSubclasses.add(classifier);
+        }
+      }
+    }
+
     if (!appView.options().enableKotlinMetadataRewritingForMembers) {
       return;
     }
@@ -92,18 +115,9 @@
       }
     }
 
-    rewriteDeclarationContainer(kmClass, appView, lens);
+    // TODO(b/70169921): enum entries
 
-    List<String> sealedSubclasses = kmClass.getSealedSubclasses();
-    sealedSubclasses.clear();
-    if (IS_SEALED.invoke(kmClass.getFlags())) {
-      for (DexType subtype : appView.appInfo().allImmediateSubtypes(clazz.type)) {
-        String classifier = toRenamedClassifier(subtype, appView, lens);
-        if (classifier != null) {
-          sealedSubclasses.add(classifier);
-        }
-      }
-    }
+    rewriteDeclarationContainer(kmClass, appView, lens);
   }
 
   @Override
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java
index e05cd9a..7ecf894 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java
@@ -10,7 +10,7 @@
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertFalse;
 
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ToolHelper;
@@ -110,16 +110,15 @@
     KmClassSubject kmClass = outer.getKmClass();
     assertThat(kmClass, isPresent());
 
+    assertFalse(kmClass.getNestedClassDescriptors().isEmpty());
     kmClass.getNestedClassDescriptors().forEach(nestedClassDescriptor -> {
       ClassSubject nestedClass = inspector.clazz(descriptorToJavaType(nestedClassDescriptor));
       if (nestedClass.getOriginalName().contains("Inner")) {
         assertThat(nestedClass, not(isRenamed()));
-        assertEquals(nestedClassDescriptor, nestedClass.getFinalDescriptor());
       } else {
         assertThat(nestedClass, isRenamed());
-        // TODO(b/70169921): nestedClass in KmClass should refer to renamed classes.
-        assertNotEquals(nestedClassDescriptor, nestedClass.getFinalDescriptor());
       }
+      assertEquals(nestedClassDescriptor, nestedClass.getFinalDescriptor());
     });
   }
 }
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java
index 6cd1034..b643c4b 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java
@@ -12,6 +12,7 @@
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -110,6 +111,7 @@
     KmClassSubject kmClass = expr.getKmClass();
     assertThat(kmClass, isPresent());
 
+    assertFalse(kmClass.getSealedSubclassDescriptors().isEmpty());
     kmClass.getSealedSubclassDescriptors().forEach(sealedSubclassDescriptor -> {
       ClassSubject sealedSubclass =
           inspector.clazz(descriptorToJavaType(sealedSubclassDescriptor));