Merge "Tests for -if rules after member renaming"
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index fa8ca13..4fa8738 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -761,7 +761,7 @@
     while (enclosing.getEnclosingClass() != null) {
       parts.set(parts.size() - 2, parts.get(parts.size() - 2) + "$" + parts.get(parts.size() - 1));
       parts.remove(parts.size() - 1);
-      enclosing = clazz.getEnclosingClass();
+      enclosing = enclosing.getEnclosingClass();
     }
     parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ".class");
     return parts;
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java
index b026c31..57ad556 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java
@@ -58,9 +58,6 @@
   }
 }
 
-// TODO(b/110141157):
-// - Add tests where fields and methods get renamed due to naming conflicts.
-// - Add tests where the then-clause of an -if rule keeps a class that has been merged into another.
 @RunWith(Parameterized.class)
 public class IfRuleWithVerticalClassMerging extends TestBase {
 
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedFieldTypeTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedFieldTypeTest.java
index a877fec..7c85a7b 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedFieldTypeTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedFieldTypeTest.java
@@ -4,6 +4,16 @@
 
 package com.android.tools.r8.shaking.ifrule.verticalclassmerging;
 
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
+
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.google.common.collect.ImmutableList;
+
 public class MergedFieldTypeTest extends MergedTypeBaseTest {
 
   static class TestClass {
@@ -33,4 +43,69 @@
   public String getExpectedStdout() {
     return B.class.getName();
   }
+
+  public static class MergedFieldTypeWithCollisionTest extends MergedTypeBaseTest {
+
+    static class SuperTestClass {
+
+      private A field = new B();
+
+      public A get() {
+        return field;
+      }
+    }
+
+    static class TestClass extends SuperTestClass {
+
+      private A field = null;
+
+      public static void main(String[] args) {
+        TestClass obj = new TestClass();
+        if (false) {
+          obj.field = new B();
+          System.out.println(obj.field);
+        }
+        System.out.print(obj.get().getClass().getName());
+      }
+    }
+
+    public MergedFieldTypeWithCollisionTest(Backend backend, boolean enableVerticalClassMerging) {
+      super(backend, enableVerticalClassMerging, ImmutableList.of(SuperTestClass.class));
+    }
+
+    @Override
+    public Class<?> getTestClass() {
+      return TestClass.class;
+    }
+
+    @Override
+    public String getConditionForProguardIfRule() {
+      return "-if class **$SuperTestClass { **$A field; }";
+    }
+
+    @Override
+    public String getExpectedStdout() {
+      return B.class.getName();
+    }
+
+    @Override
+    public void inspect(CodeInspector inspector) {
+      super.inspect(inspector);
+
+      ClassSubject testClassSubject = inspector.clazz(TestClass.class);
+      assertThat(testClassSubject, isPresent());
+
+      if (enableVerticalClassMerging) {
+        // Verify that SuperTestClass has been merged into TestClass.
+        assertThat(inspector.clazz(SuperTestClass.class), not(isPresent()));
+        assertEquals("java.lang.Object", testClassSubject.getDexClass().superType.toSourceString());
+
+        // Verify that TestClass.field has been removed.
+        assertEquals(1, testClassSubject.allFields().size());
+
+        // Verify that there was a naming conflict such that SuperTestClass.field was renamed.
+        assertNotEquals("field", testClassSubject.allFields().get(0).getFinalName());
+      }
+    }
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedParameterTypeTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedParameterTypeTest.java
index 7447efd1..d8c1f29 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedParameterTypeTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedParameterTypeTest.java
@@ -4,6 +4,19 @@
 
 package com.android.tools.r8.shaking.ifrule.verticalclassmerging;
 
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
+
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.stream.Collectors;
+
 public class MergedParameterTypeTest extends MergedTypeBaseTest {
 
   static class TestClass {
@@ -35,4 +48,73 @@
   public String getExpectedStdout() {
     return B.class.getName();
   }
+
+  public static class MergedParameterTypeWithCollisionTest extends MergedTypeBaseTest {
+
+    static class SuperTestClass {
+
+      public static void method(A obj) {
+        System.out.print(obj.getClass().getName());
+      }
+    }
+
+    static class TestClass extends SuperTestClass {
+
+      public static void main(String[] args) {
+        B obj = new B();
+        if (obj == null) {
+          TestClass.method(obj);
+        }
+        SuperTestClass.method(obj);
+      }
+
+      public static void method(A obj) {
+        System.out.print(obj.getClass().getName());
+      }
+    }
+
+    public MergedParameterTypeWithCollisionTest(
+        Backend backend, boolean enableVerticalClassMerging) {
+      super(backend, enableVerticalClassMerging, ImmutableList.of(SuperTestClass.class));
+    }
+
+    @Override
+    public Class<?> getTestClass() {
+      return TestClass.class;
+    }
+
+    @Override
+    public String getConditionForProguardIfRule() {
+      return "-if class **$SuperTestClass { void method(**$A); }";
+    }
+
+    @Override
+    public String getExpectedStdout() {
+      return B.class.getName();
+    }
+
+    @Override
+    public void inspect(CodeInspector inspector) {
+      super.inspect(inspector);
+
+      ClassSubject testClassSubject = inspector.clazz(TestClass.class);
+      assertThat(testClassSubject, isPresent());
+
+      if (enableVerticalClassMerging) {
+        // Verify that SuperTestClass has been merged into TestClass.
+        assertThat(inspector.clazz(SuperTestClass.class), not(isPresent()));
+        assertEquals("java.lang.Object", testClassSubject.getDexClass().superType.toSourceString());
+
+        // Verify that TestClass.method has been removed.
+        List<FoundMethodSubject> methods =
+            testClassSubject.allMethods().stream()
+                .filter(subject -> subject.getFinalName().contains("method"))
+                .collect(Collectors.toList());
+        assertEquals(1, methods.size());
+
+        // Verify that there was a naming conflict such that SuperTestClass.method was renamed.
+        assertNotEquals("method", methods.get(0).getFinalName());
+      }
+    }
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedReturnTypeTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedReturnTypeTest.java
index da4a9f1..e1b071f 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedReturnTypeTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedReturnTypeTest.java
@@ -4,6 +4,19 @@
 
 package com.android.tools.r8.shaking.ifrule.verticalclassmerging;
 
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
+
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.stream.Collectors;
+
 public class MergedReturnTypeTest extends MergedTypeBaseTest {
 
   static class TestClass {
@@ -35,4 +48,72 @@
   public String getExpectedStdout() {
     return B.class.getName();
   }
+
+  public static class MergedReturnTypeWithCollisionTest extends MergedTypeBaseTest {
+
+    static class SuperTestClass {
+
+      public static A method() {
+        return new B();
+      }
+    }
+
+    static class TestClass extends SuperTestClass {
+
+      public static void main(String[] args) {
+        B obj = new B();
+        if (obj == null) {
+          System.out.print(TestClass.method().getClass().getName());
+        }
+        System.out.print(SuperTestClass.method().getClass().getName());
+      }
+
+      public static A method() {
+        return new B();
+      }
+    }
+
+    public MergedReturnTypeWithCollisionTest(Backend backend, boolean enableVerticalClassMerging) {
+      super(backend, enableVerticalClassMerging, ImmutableList.of(SuperTestClass.class));
+    }
+
+    @Override
+    public Class<?> getTestClass() {
+      return TestClass.class;
+    }
+
+    @Override
+    public String getConditionForProguardIfRule() {
+      return "-if class **$SuperTestClass { **$A method(); }";
+    }
+
+    @Override
+    public String getExpectedStdout() {
+      return B.class.getName();
+    }
+
+    @Override
+    public void inspect(CodeInspector inspector) {
+      super.inspect(inspector);
+
+      ClassSubject testClassSubject = inspector.clazz(TestClass.class);
+      assertThat(testClassSubject, isPresent());
+
+      if (enableVerticalClassMerging) {
+        // Verify that SuperTestClass has been merged into TestClass.
+        assertThat(inspector.clazz(SuperTestClass.class), not(isPresent()));
+        assertEquals("java.lang.Object", testClassSubject.getDexClass().superType.toSourceString());
+
+        // Verify that TestClass.method has been removed.
+        List<FoundMethodSubject> methods =
+            testClassSubject.allMethods().stream()
+                .filter(subject -> subject.getFinalName().contains("method"))
+                .collect(Collectors.toList());
+        assertEquals(1, methods.size());
+
+        // Verify that there was a naming conflict such that SuperTestClass.method was renamed.
+        assertNotEquals("method", methods.get(0).getFinalName());
+      }
+    }
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedTypeBaseTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedTypeBaseTest.java
index ac341eb..2b9fec7 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedTypeBaseTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedTypeBaseTest.java
@@ -27,10 +27,6 @@
 @RunWith(Parameterized.class)
 public abstract class MergedTypeBaseTest extends TestBase {
 
-  private final List<Class> CLASSES =
-      ImmutableList.of(
-          A.class, B.class, C.class, I.class, J.class, K.class, Unused.class, getTestClass());
-
   static class A {}
 
   static class B extends A {}
@@ -46,11 +42,22 @@
   static class Unused {}
 
   final Backend backend;
+  final List<Class> classes;
   final boolean enableVerticalClassMerging;
 
   public MergedTypeBaseTest(Backend backend, boolean enableVerticalClassMerging) {
+    this(backend, enableVerticalClassMerging, ImmutableList.of());
+  }
+
+  public MergedTypeBaseTest(
+      Backend backend, boolean enableVerticalClassMerging, List<Class<?>> additionalClasses) {
     this.backend = backend;
     this.enableVerticalClassMerging = enableVerticalClassMerging;
+    this.classes =
+        ImmutableList.<Class>builder()
+            .add(A.class, B.class, C.class, Unused.class, getTestClass())
+            .addAll(additionalClasses)
+            .build();
   }
 
   @Parameters(name = "Backend: {0}, vertical class merging: {1}")
@@ -96,7 +103,7 @@
             getConditionForProguardIfRule(),
             "-keep class " + Unused.class.getTypeName(),
             getAdditionalKeepRules());
-    AndroidApp output = compileWithR8(readClasses(CLASSES), config, this::configure, backend);
+    AndroidApp output = compileWithR8(readClasses(classes), config, this::configure, backend);
     assertEquals(expected, runOnVM(output, getTestClass(), backend));
     inspect(new CodeInspector(output));
   }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java
index 90013b0..e76991b 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java
@@ -56,6 +56,12 @@
 
   public abstract void forAllFields(Consumer<FoundFieldSubject> inspection);
 
+  public final List<FoundFieldSubject> allFields() {
+    ImmutableList.Builder<FoundFieldSubject> builder = ImmutableList.builder();
+    forAllFields(builder::add);
+    return builder.build();
+  }
+
   public abstract FieldSubject field(String type, String name);
 
   public FoundClassSubject asFoundClassSubject() {
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
index 1d308fc..ed71b96 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
@@ -20,7 +20,6 @@
 import com.android.tools.r8.naming.MemberNaming.Signature;
 import com.android.tools.r8.naming.signature.GenericSignatureParser;
 import com.android.tools.r8.utils.DescriptorUtils;
-import com.google.common.collect.ImmutableList;
 import java.util.List;
 import java.util.function.Consumer;
 
@@ -109,12 +108,6 @@
         inspection);
   }
 
-  public List<FoundFieldSubject> allFields() {
-    ImmutableList.Builder<FoundFieldSubject> builder = ImmutableList.builder();
-    forAllFields(builder::add);
-    return builder.build();
-  }
-
   @Override
   public FieldSubject field(String type, String name) {
     String obfuscatedType = codeInspector.getObfuscatedTypeName(type);