blob: 0a3058ae09d3624f9070efcd20dcb713a0282773 [file] [log] [blame]
// 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 {}