| // Copyright (c) 2019, 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.proguard.configuration; | 
 |  | 
 | import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; | 
 | import static org.hamcrest.CoreMatchers.containsString; | 
 | import static org.hamcrest.MatcherAssert.assertThat; | 
 | import static org.junit.Assert.assertEquals; | 
 | import static org.junit.Assert.fail; | 
 |  | 
 | import com.android.tools.r8.CompilationFailedException; | 
 | import com.android.tools.r8.TestBase; | 
 | import com.android.tools.r8.TestShrinkerBuilder; | 
 | import com.android.tools.r8.utils.ThrowingConsumer; | 
 | import com.android.tools.r8.utils.codeinspector.CodeInspector; | 
 | import com.google.common.collect.ImmutableList; | 
 | import java.util.List; | 
 | import org.junit.Ignore; | 
 | import org.junit.Test; | 
 |  | 
 | public class InheritanceClauseWithDisjunctionTest extends TestBase { | 
 |  | 
 |   @Ignore("b/128503974") | 
 |   @Test | 
 |   public void testExtendsClauseWithR8() throws Exception { | 
 |     runTest( | 
 |         testForR8(Backend.DEX), | 
 |         getKeepRulesForExtendsClauseTests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectExtendsClauseTests); | 
 |   } | 
 |  | 
 |   @Test | 
 |   public void testExtendsClauseWithProguard() throws Exception { | 
 |     runTest( | 
 |         testForProguard(), | 
 |         getKeepRulesForExtendsClauseTests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectExtendsClauseTests); | 
 |   } | 
 |  | 
 |   private static List<String> getKeepRulesForExtendsClauseTests() { | 
 |     return ImmutableList.of( | 
 |         "-keep class * extends " | 
 |             + InheritanceClauseWithDisjunctionTestClassA.class.getTypeName() | 
 |             + ", " | 
 |             + InheritanceClauseWithDisjunctionTestClassB.class.getTypeName() | 
 |             + ", " | 
 |             + InheritanceClauseWithDisjunctionTestClassC.class.getTypeName()); | 
 |   } | 
 |  | 
 |   private static void inspectExtendsClauseTests(CodeInspector inspector) { | 
 |     // ASub extends A and BSub extends B. A and B are kept because Proguard presumably does not | 
 |     // merge them into ASub and BSub, respectively. | 
 |     assertEquals(4, inspector.allClasses().size()); | 
 |     assertThat(inspector.clazz(InheritanceClauseWithDisjunctionTestClassA.class), isPresent()); | 
 |     assertThat(inspector.clazz(InheritanceClauseWithDisjunctionTestClassASub.class), isPresent()); | 
 |     assertThat(inspector.clazz(InheritanceClauseWithDisjunctionTestClassB.class), isPresent()); | 
 |     assertThat(inspector.clazz(InheritanceClauseWithDisjunctionTestClassBSub.class), isPresent()); | 
 |   } | 
 |  | 
 |   @Ignore("b/128503974") | 
 |   @Test | 
 |   public void testExtendsClauseWithNegation1WithR8() throws Exception { | 
 |     runTest( | 
 |         testForR8(Backend.DEX), | 
 |         getKeepRulesForExtendsClauseWithNegation1Tests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectExtendsClauseWithNegation1Tests); | 
 |   } | 
 |  | 
 |   @Test | 
 |   public void testExtendsClauseWithNegation1WithProguard() throws Exception { | 
 |     runTest( | 
 |         testForProguard(), | 
 |         getKeepRulesForExtendsClauseWithNegation1Tests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectExtendsClauseWithNegation1Tests); | 
 |   } | 
 |  | 
 |   private static List<String> getKeepRulesForExtendsClauseWithNegation1Tests() { | 
 |     return ImmutableList.of( | 
 |         "-keep class * extends " | 
 |             + InheritanceClauseWithDisjunctionTestClassA.class.getTypeName() | 
 |             + ", !" | 
 |             + InheritanceClauseWithDisjunctionTestClassB.class.getTypeName()); | 
 |   } | 
 |  | 
 |   private static void inspectExtendsClauseWithNegation1Tests(CodeInspector inspector) { | 
 |     // Strangely, BSub is kept, although it does not extend A and it extends B. | 
 |     assertEquals(11, inspector.allClasses().size()); | 
 |   } | 
 |  | 
 |   @Ignore("b/128503974") | 
 |   @Test | 
 |   public void testExtendsClauseWithNegation2WithR8() throws Exception { | 
 |     runTest( | 
 |         testForR8(Backend.DEX), | 
 |         getKeepRulesForExtendsClauseWithNegation2Tests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectExtendsClauseWithNegation2Tests); | 
 |   } | 
 |  | 
 |   @Test | 
 |   public void testExtendsClauseWithNegation2WithProguard() throws Exception { | 
 |     runTest( | 
 |         testForProguard(), | 
 |         getKeepRulesForExtendsClauseWithNegation2Tests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectExtendsClauseWithNegation2Tests); | 
 |   } | 
 |  | 
 |   private static List<String> getKeepRulesForExtendsClauseWithNegation2Tests() { | 
 |     return ImmutableList.of( | 
 |         "-keep class * extends !" | 
 |             + InheritanceClauseWithDisjunctionTestClassB.class.getTypeName() | 
 |             + ", " | 
 |             + InheritanceClauseWithDisjunctionTestClassA.class.getTypeName()); | 
 |   } | 
 |  | 
 |   private static void inspectExtendsClauseWithNegation2Tests(CodeInspector inspector) { | 
 |     // Strangely, all the types that do not extend A have not kept. | 
 |     assertEquals(2, inspector.allClasses().size()); | 
 |     assertThat(inspector.clazz(InheritanceClauseWithDisjunctionTestClassA.class), isPresent()); | 
 |     assertThat(inspector.clazz(InheritanceClauseWithDisjunctionTestClassASub.class), isPresent()); | 
 |   } | 
 |  | 
 |   @Ignore("b/128503974") | 
 |   @Test | 
 |   public void testExtendsClauseWithMatchAllNegationWithR8() throws Exception { | 
 |     runTest( | 
 |         testForR8(Backend.DEX), | 
 |         getKeepRulesForExtendsClauseWithMatchAllNegationTests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectExtendsClauseWithMatchAllNegationTests); | 
 |   } | 
 |  | 
 |   @Test | 
 |   public void testExtendsClauseWithMatchAllNegationWithProguard() throws Exception { | 
 |     runTest( | 
 |         testForProguard(), | 
 |         getKeepRulesForExtendsClauseWithMatchAllNegationTests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectExtendsClauseWithMatchAllNegationTests); | 
 |   } | 
 |  | 
 |   private static List<String> getKeepRulesForExtendsClauseWithMatchAllNegationTests() { | 
 |     return ImmutableList.of( | 
 |         "-keep class * extends " | 
 |             + InheritanceClauseWithDisjunctionTestClassA.class.getTypeName() | 
 |             + ", !" | 
 |             + InheritanceClauseWithDisjunctionTestClassA.class.getTypeName()); | 
 |   } | 
 |  | 
 |   private static void inspectExtendsClauseWithMatchAllNegationTests(CodeInspector inspector) { | 
 |     // Every type extends A or does not extend A. | 
 |     assertEquals(11, inspector.allClasses().size()); | 
 |   } | 
 |  | 
 |   @Ignore("b/128503974") | 
 |   @Test | 
 |   public void testImplementsClauseWithR8() throws Exception { | 
 |     runTest( | 
 |         testForR8(Backend.DEX), | 
 |         getKeepRulesForImplementsClauseTests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectImplementsClauseTests); | 
 |   } | 
 |  | 
 |   @Test | 
 |   public void testImplementsClauseWithProguard() throws Exception { | 
 |     try { | 
 |       runTest( | 
 |           testForProguard(), | 
 |           getKeepRulesForImplementsClauseTests(), | 
 |           InheritanceClauseWithDisjunctionTest::inspectImplementsClauseTests); | 
 |       fail(); | 
 |     } catch (CompilationFailedException e) { | 
 |       // Strangely, nothing matches implements I or J (not even InheritanceClauseWithDisjunction- | 
 |       // TestClassIJSub, which implements both I and J!). | 
 |       assertThat(e.getMessage(), containsString("The output jar is empty")); | 
 |     } | 
 |   } | 
 |  | 
 |   private static List<String> getKeepRulesForImplementsClauseTests() { | 
 |     return ImmutableList.of( | 
 |         "-keep class * implements " | 
 |             + InheritanceClauseWithDisjunctionTestInterfaceI.class.getTypeName() | 
 |             + ", " | 
 |             + InheritanceClauseWithDisjunctionTestInterfaceJ.class.getTypeName() | 
 |             + ", " | 
 |             + InheritanceClauseWithDisjunctionTestInterfaceK.class.getTypeName()); | 
 |   } | 
 |  | 
 |   private static void inspectImplementsClauseTests(CodeInspector inspector) { | 
 |     // Strangely, nothing matches implements I or J (not even InheritanceClauseWithDisjunctionTest- | 
 |     // ClassIJSub, which implements both I and J!). | 
 |     assertEquals(0, inspector.allClasses().size()); | 
 |   } | 
 |  | 
 |   @Ignore("b/128503974") | 
 |   @Test | 
 |   public void testImplementsClauseWithNegationWithR8() throws Exception { | 
 |     runTest( | 
 |         testForR8(Backend.DEX), | 
 |         getKeepRulesForImplementsClauseTests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectImplementsClauseWithNegationTests); | 
 |   } | 
 |  | 
 |   @Test | 
 |   public void testImplementsClauseWithNegationWithProguard() throws Exception { | 
 |     runTest( | 
 |         testForProguard(), | 
 |         getKeepRulesForImplementsClauseWithNegationTests(), | 
 |         InheritanceClauseWithDisjunctionTest::inspectImplementsClauseWithNegationTests); | 
 |   } | 
 |  | 
 |   private static List<String> getKeepRulesForImplementsClauseWithNegationTests() { | 
 |     return ImmutableList.of( | 
 |         "-keep class * implements " | 
 |             + InheritanceClauseWithDisjunctionTestInterfaceI.class.getTypeName() | 
 |             + ", !" | 
 |             + InheritanceClauseWithDisjunctionTestInterfaceI.class.getTypeName()); | 
 |   } | 
 |  | 
 |   private static void inspectImplementsClauseWithNegationTests(CodeInspector inspector) { | 
 |     // Every type implements I or does not implement I. | 
 |     assertEquals(11, inspector.allClasses().size()); | 
 |   } | 
 |  | 
 |   private static void runTest( | 
 |       TestShrinkerBuilder<?, ?, ?, ?, ?> builder, | 
 |       List<String> keepRules, | 
 |       ThrowingConsumer<CodeInspector, RuntimeException> consumer) | 
 |       throws Exception { | 
 |     builder | 
 |         .addProgramClasses( | 
 |             InheritanceClauseWithDisjunctionTestClassA.class, | 
 |             InheritanceClauseWithDisjunctionTestClassASub.class, | 
 |             InheritanceClauseWithDisjunctionTestClassB.class, | 
 |             InheritanceClauseWithDisjunctionTestClassBSub.class, | 
 |             InheritanceClauseWithDisjunctionTestClassC.class, | 
 |             InheritanceClauseWithDisjunctionTestInterfaceI.class, | 
 |             InheritanceClauseWithDisjunctionTestClassISub.class, | 
 |             InheritanceClauseWithDisjunctionTestInterfaceJ.class, | 
 |             InheritanceClauseWithDisjunctionTestClassJSub.class, | 
 |             InheritanceClauseWithDisjunctionTestInterfaceK.class, | 
 |             InheritanceClauseWithDisjunctionTestClassIJKSub.class) | 
 |         .addKeepRules(keepRules) | 
 |         .compile() | 
 |         .inspect(consumer); | 
 |   } | 
 | } | 
 |  | 
 | class InheritanceClauseWithDisjunctionTestClassA {} | 
 |  | 
 | class InheritanceClauseWithDisjunctionTestClassASub | 
 |     extends InheritanceClauseWithDisjunctionTestClassA {} | 
 |  | 
 | class InheritanceClauseWithDisjunctionTestClassB {} | 
 |  | 
 | class InheritanceClauseWithDisjunctionTestClassBSub | 
 |     extends InheritanceClauseWithDisjunctionTestClassB {} | 
 |  | 
 | class InheritanceClauseWithDisjunctionTestClassC {} | 
 |  | 
 | interface InheritanceClauseWithDisjunctionTestInterfaceI {} | 
 |  | 
 | class InheritanceClauseWithDisjunctionTestClassISub | 
 |     implements InheritanceClauseWithDisjunctionTestInterfaceI {} | 
 |  | 
 | interface InheritanceClauseWithDisjunctionTestInterfaceJ {} | 
 |  | 
 | class InheritanceClauseWithDisjunctionTestClassJSub | 
 |     implements InheritanceClauseWithDisjunctionTestInterfaceJ {} | 
 |  | 
 | interface InheritanceClauseWithDisjunctionTestInterfaceK {} | 
 |  | 
 | class InheritanceClauseWithDisjunctionTestClassIJKSub | 
 |     implements InheritanceClauseWithDisjunctionTestInterfaceI, | 
 |         InheritanceClauseWithDisjunctionTestInterfaceJ, | 
 |         InheritanceClauseWithDisjunctionTestInterfaceK {} |