Pin soft pinned classes when type becomes live

Bug: 189443104
Change-Id: I697b977ef50d104d894c8af231f3617e6ede741e
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index f6d9e6e..f3d898f 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -1797,6 +1797,8 @@
       enqueueFirstNonSerializableClassInitializer(clazz, reason);
     }
 
+    checkDefinitionForSoftPinning(clazz);
+
     processAnnotations(clazz);
 
     // If this type has deferred annotations, we have to process those now, too.
@@ -2602,7 +2604,7 @@
     // Add all dependent members to the workqueue.
     enqueueRootItems(rootSet.getDependentItems(field.getDefinition()));
 
-    checkMemberForSoftPinning(field);
+    checkDefinitionForSoftPinning(field);
 
     // Notify analyses.
     analyses.forEach(analysis -> analysis.processNewlyLiveField(field, context));
@@ -3851,7 +3853,7 @@
     // Add all dependent members to the workqueue.
     enqueueRootItems(rootSet.getDependentItems(definition));
 
-    checkMemberForSoftPinning(method);
+    checkDefinitionForSoftPinning(method);
 
     // Notify analyses.
     analyses.forEach(analysis -> analysis.processNewlyLiveMethod(method, context));
@@ -3898,15 +3900,15 @@
     method.registerCodeReferences(useRegistryFactory.create(appView, method, this));
   }
 
-  private void checkMemberForSoftPinning(ProgramMember<?, ?> member) {
-    DexMember<?, ?> reference = member.getDefinition().getReference();
+  private void checkDefinitionForSoftPinning(ProgramDefinition definition) {
+    DexReference reference = definition.getReference();
     Set<ProguardKeepRuleBase> softPinRules = rootSet.softPinned.getRulesForReference(reference);
     if (softPinRules != null) {
       assert softPinRules.stream().noneMatch(r -> r.getModifiers().allowsOptimization);
       keepInfo.joinInfo(reference, appInfo, Joiner::pin);
     }
     // Identify dependent soft pinning.
-    MutableItemsWithRules items = rootSet.dependentSoftPinned.get(member.getHolderType());
+    MutableItemsWithRules items = rootSet.dependentSoftPinned.get(definition.getContextType());
     if (items != null && items.containsReference(reference)) {
       assert items.getRulesForReference(reference).stream()
           .noneMatch(r -> r.getModifiers().allowsOptimization);
diff --git a/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureAllowShrinkingTest.java b/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureAllowShrinkingTest.java
index 46e1a82..be24a34 100644
--- a/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureAllowShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureAllowShrinkingTest.java
@@ -46,7 +46,7 @@
         .addKeepAttributes(ProguardKeepAttributes.SIGNATURE)
         .addKeepMainRule(Main.class)
         .run(parameters.getRuntime(), Main.class)
-        .inspect(inspector -> inspect(inspector, true))
+        .inspect(this::inspect)
         .assertSuccessWithOutputLines(EXPECTED);
   }
 
@@ -62,26 +62,20 @@
                 + " { *; }")
         .addKeepAttributes(ProguardKeepAttributes.SIGNATURE)
         .addKeepMainRule(Main.class)
-        .compile()
-        // TODO(b/189443104): Should keep signature.
-        .inspect(inspector -> inspect(inspector, false))
         .run(parameters.getRuntime(), Main.class)
-        // TODO(b/189443104): Should succeed.
-        .assertFailureWithErrorThatThrows(ClassCastException.class);
+        .inspect(this::inspect)
+        .assertSuccessWithOutputLines(EXPECTED);
   }
 
-  private void inspect(CodeInspector inspector, boolean keptSignature) {
+  private void inspect(CodeInspector inspector) {
     ClassSubject foo = inspector.clazz(Foo.class);
     assertThat(foo, isPresent());
-    assertEquals(
-        keptSignature ? "<T:Ljava/lang/Object;>Ljava/lang/Object;" : null,
-        foo.getFinalSignatureAttribute());
+    assertEquals("<T:Ljava/lang/Object;>Ljava/lang/Object;", foo.getFinalSignatureAttribute());
 
     ClassSubject main$1 = inspector.clazz(Main.class.getTypeName() + "$1");
     assertThat(main$1, isPresent());
     assertEquals(
-        keptSignature ? "L" + binaryName(Foo.class) + "<Ljava/lang/String;>;" : null,
-        main$1.getFinalSignatureAttribute());
+        "L" + binaryName(Foo.class) + "<Ljava/lang/String;>;", main$1.getFinalSignatureAttribute());
   }
 
   public static class Foo<T> {
diff --git a/src/test/java/com/android/tools/r8/shaking/allowshrinking/KeepClassAllowShrinkingCompatibilityTest.java b/src/test/java/com/android/tools/r8/shaking/allowshrinking/KeepClassAllowShrinkingCompatibilityTest.java
index 7dc40c3..5ee49f5 100644
--- a/src/test/java/com/android/tools/r8/shaking/allowshrinking/KeepClassAllowShrinkingCompatibilityTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/allowshrinking/KeepClassAllowShrinkingCompatibilityTest.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.shaking.allowshrinking;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.TestBase;
@@ -54,11 +53,10 @@
         .compile()
         .inspect(
             inspector -> {
-              // TODO(b/189443104): Should keep A and B.
               ClassSubject aSubject = inspector.clazz(A.class);
-              assertThat(aSubject, shrinker.isR8() ? not(isPresent()) : isPresent());
+              assertThat(aSubject, isPresent());
               ClassSubject bSubject = inspector.clazz(B.class);
-              assertThat(bSubject, shrinker.isR8() ? not(isPresent()) : isPresent());
+              assertThat(bSubject, isPresent());
             })
         .run(parameters.getRuntime(), Main.class)
         .assertSuccessWithEmptyOutput();