blob: a9fc20f6a2f900b4c86c16e45f8d20338d7ffbc7 [file] [log] [blame]
// Copyright (c) 2020, 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.naming.signature;
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.CompilationFailedException;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.naming.signature.merging.I;
import com.android.tools.r8.naming.signature.merging.ImplI;
import com.android.tools.r8.naming.signature.merging.ImplK;
import com.android.tools.r8.naming.signature.merging.InterfaceToKeep;
import com.android.tools.r8.naming.signature.merging.J;
import com.android.tools.r8.naming.signature.merging.K;
import java.io.IOException;
import java.lang.invoke.LambdaConversionException;
import java.lang.reflect.Type;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class SignatureOfMergedClassesTest extends TestBase {
private final TestParameters parameters;
@Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withAllRuntimesAndApiLevels().build();
}
public SignatureOfMergedClassesTest(TestParameters parameters) {
this.parameters = parameters;
}
@Test
public void testRemovalOfMergedInterfaceOnSameClass()
throws IOException, CompilationFailedException, ExecutionException,
LambdaConversionException {
testForR8(parameters.getBackend())
.addProgramClasses(
ImplI.class, ImplK.class, I.class, J.class, InterfaceToKeep.class, K.class, Main.class)
.addKeepMainRule(Main.class)
.addKeepClassRules(InterfaceToKeep.class)
.addKeepAttributes("Signature, InnerClasses, EnclosingMethod, *Annotation*")
.setMinApi(parameters.getApiLevel())
.noMinification()
.addOptionsModification(
internalOptions -> {
internalOptions.enableUnusedInterfaceRemoval = false;
})
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLines(
"ImplI.foo",
"ImplI: com.android.tools.r8.naming.signature.merging.InterfaceToKeep<java.lang.Void>",
"K: com.android.tools.r8.naming.signature.merging.InterfaceToKeep<java.lang.Void>",
"ImplK.foo",
"ImplK.bar",
"ImplK: interface com.android.tools.r8.naming.signature.merging.K")
.inspect(
codeInspector -> {
assertThat(codeInspector.clazz(I.class), not(isPresent()));
assertThat(codeInspector.clazz(J.class), not(isPresent()));
});
}
@Test
public void testKeepingOneSelfOnInterface()
throws ExecutionException, CompilationFailedException, IOException {
testForR8(parameters.getBackend())
.addProgramClasses(Foo.class, InterfaceToKeep.class)
.addKeepMainRule(Foo.class)
.addKeepClassRules(InterfaceToKeep.class)
.addKeepAttributes("Signature, InnerClasses, EnclosingMethod, *Annotation*")
.setMinApi(parameters.getApiLevel())
.noMinification()
.addOptionsModification(
internalOptions -> {
internalOptions.enableUnusedInterfaceRemoval = false;
})
.run(parameters.getRuntime(), Foo.class)
.assertSuccessWithOutputLines(
"com.android.tools.r8.naming.signature.merging.InterfaceToKeep"
+ "<com.android.tools.r8.naming.signature.SignatureOfMergedClassesTest$Foo>");
}
public static class Foo implements InterfaceToKeep<Foo> {
public static void main(String[] args) {
for (Type genericInterface : Foo.class.getGenericInterfaces()) {
System.out.println(genericInterface);
}
}
}
public static class Main {
public static void main(String[] args) {
new ImplI().foo();
for (Type genericInterface : ImplI.class.getGenericInterfaces()) {
System.out.println("ImplI: " + genericInterface);
}
for (Type genericInterface : K.class.getGenericInterfaces()) {
System.out.println("K: " + genericInterface);
}
K k = new ImplK();
k.foo();
k.bar();
for (Type genericInterface : ImplK.class.getGenericInterfaces()) {
System.out.println("ImplK: " + genericInterface);
}
}
}
}