diff options
Diffstat (limited to 'src/test/java/com/android/tools/r8/classmerging/StaticClassMergerInterfaceTest.java')
-rw-r--r-- | src/test/java/com/android/tools/r8/classmerging/StaticClassMergerInterfaceTest.java | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/test/java/com/android/tools/r8/classmerging/StaticClassMergerInterfaceTest.java b/src/test/java/com/android/tools/r8/classmerging/StaticClassMergerInterfaceTest.java new file mode 100644 index 000000000..294eca0c7 --- /dev/null +++ b/src/test/java/com/android/tools/r8/classmerging/StaticClassMergerInterfaceTest.java @@ -0,0 +1,105 @@ +// Copyright (c) 2018, 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.classmerging; + +import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent; +import static org.hamcrest.core.IsNot.not; +import static org.junit.Assert.assertThat; + +import com.android.tools.r8.NeverClassInline; +import com.android.tools.r8.NeverInline; +import com.android.tools.r8.TestBase; +import com.android.tools.r8.ToolHelper; +import com.android.tools.r8.ToolHelper.DexVm.Version; +import com.android.tools.r8.utils.StringUtils; +import com.android.tools.r8.utils.codeinspector.CodeInspector; +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 StaticClassMergerInterfaceTest extends TestBase { + + private final Backend backend; + + @Parameters(name = "Backend: {0}") + public static Backend[] data() { + return Backend.values(); + } + + public StaticClassMergerInterfaceTest(Backend backend) { + this.backend = backend; + } + + @Test + public void test() throws Exception { + String expectedOutput = StringUtils.lines("In A.a()", "In B.b()", "In C.c()"); + + CodeInspector inspector = + testForR8(backend) + .addInnerClasses(StaticClassMergerInterfaceTest.class) + .addKeepMainRule(TestClass.class) + .addKeepRules("-dontobfuscate") + .enableInliningAnnotations() + .enableClassInliningAnnotations() + .run(TestClass.class) + .assertSuccessWithOutput(expectedOutput) + .inspector(); + + // Check that A has not been merged into B. The static class merger visits classes in alpha- + // betical order. By the time A is processed, there is no merge representative and A is not + // a valid merge representative itself, because it is an interface. + if (ToolHelper.getDexVm().getVersion().isNewerThan(Version.V6_0_1) || backend == Backend.CF) { + assertThat(inspector.clazz(A.class), isPresent()); + } else { + assertThat(inspector.clazz(A.class.getTypeName() + "$-CC"), isPresent()); + } + + + // By the time B is processed, there is no merge representative, so it should be present. + assertThat(inspector.clazz(B.class), isPresent()); + + // By the time C is processed, B should be merge candidate. Therefore, we should allow C.c() to + // be moved to B *although C is an interface*. + assertThat(inspector.clazz(C.class), not(isPresent())); + } + + static class TestClass { + + public static void main(String[] args) { + A.a(); + B.b(); + C.c(); + } + } + + @NeverClassInline + interface A { + + @NeverInline + static void a() { + System.out.println("In A.a()"); + } + } + + @NeverClassInline + static class B { + + @NeverInline + static void b() { + System.out.println("In B.b()"); + } + } + + @NeverClassInline + interface C { + + @NeverInline + static void c() { + System.out.println("In C.c()"); + } + } +} |