blob: df4566a3715ce6fb1918d2d567986a0e67784ec1 [file]
// 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.desugar;
import static com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringForTesting.getCompanionClassNameSuffix;
import com.android.tools.r8.DesugarTestConfiguration;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.concurrent.Callable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class DesugarInnerClassesInInterfacesTest extends TestBase {
private final List<String> EXPECTED_RESULT_WITHOUT_DESUGARING =
ImmutableList.of(
WithAnonymousInner.class.getName(),
WithAnonymousInner.class.getName(),
WithLocalInner.class.getName(),
WithLocalInner.class.getName());
private final List<String> EXPECTED_RESULT_WITH_DESUGARING =
ImmutableList.of(
WithAnonymousInner.class.getName() + getCompanionClassNameSuffix(),
WithAnonymousInner.class.getName() + getCompanionClassNameSuffix(),
WithLocalInner.class.getName() + getCompanionClassNameSuffix(),
WithLocalInner.class.getName() + getCompanionClassNameSuffix());
private final List<String> EXPECTED_RESULT_WITH_DESUGARING_R8 =
ImmutableList.of("null", "null", "null", "null");
@Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters()
.withAllRuntimes()
.withAllApiLevelsAlsoForCf()
.withPartialCompilation()
.build();
}
@Parameter(0)
public TestParameters parameters;
@Test
public void testDesugar() throws Exception {
testForDesugaring(parameters)
.addInnerClasses(getClass())
.run(parameters.getRuntime(), TestClass.class)
.applyIf(
DesugarTestConfiguration::isNotDesugared,
r -> r.assertSuccessWithOutputLines(EXPECTED_RESULT_WITHOUT_DESUGARING))
.applyIf(
DesugarTestConfiguration::isDesugared,
r ->
r.assertSuccessWithOutputLines(
parameters
.getApiLevel()
.isGreaterThanOrEqualTo(apiLevelWithDefaultInterfaceMethodsSupport())
? EXPECTED_RESULT_WITHOUT_DESUGARING
: EXPECTED_RESULT_WITH_DESUGARING));
}
@Test
public void testR8Compat() throws Exception {
parameters.assumeR8TestParameters();
parameters.assumeNoPartialCompilation("TODO");
testForR8Compat(parameters.getBackend())
.addInnerClasses(getClass())
.setMinApi(parameters)
.addKeepAllClassesRule()
.addKeepAttributeInnerClassesAndEnclosingMethod()
.noHorizontalClassMergingOfSynthetics()
.compile()
.run(parameters.getRuntime(), TestClass.class)
.applyIf(
parameters.isCfRuntime() || parameters.canUseDefaultAndStaticInterfaceMethods(),
result -> result.assertSuccessWithOutputLines(EXPECTED_RESULT_WITHOUT_DESUGARING),
result -> result.assertSuccessWithOutputLines(EXPECTED_RESULT_WITH_DESUGARING_R8));
}
@Test
public void testR8Full() throws Exception {
parameters.assumeR8TestParameters();
parameters.assumeNoPartialCompilation("TODO");
testForR8(parameters.getBackend())
.addInnerClasses(getClass())
.setMinApi(parameters)
.addKeepAllClassesRule()
.addKeepAttributeInnerClassesAndEnclosingMethod()
.compile()
.run(parameters.getRuntime(), TestClass.class)
.applyIf(
parameters.isCfRuntime() || parameters.canUseDefaultAndStaticInterfaceMethods(),
result -> result.assertSuccessWithOutputLines(EXPECTED_RESULT_WITHOUT_DESUGARING),
result -> result.assertSuccessWithOutputLines(EXPECTED_RESULT_WITH_DESUGARING_R8));
}
interface WithAnonymousInner {
static Callable<Class<?>> staticOuter() {
return new Callable<Class<?>>() {
@Override
public Class<?> call() {
return getClass().getEnclosingClass();
}
};
}
default Callable<Class<?>> defaultOuter() {
return new Callable<Class<?>>() {
@Override
public Class<?> call() {
return getClass().getEnclosingClass();
}
};
}
}
interface WithLocalInner {
static Callable<Class<?>> staticOuter() {
class Local implements Callable<Class<?>> {
@Override
public Class<?> call() {
return getClass().getEnclosingClass();
}
}
return new Local();
}
default Callable<Class<?>> defaultOuter() {
class Local implements Callable<Class<?>> {
@Override
public Class<?> call() {
return getClass().getEnclosingClass();
}
}
return new Local();
}
}
public static class TestClass {
public static void main(String[] args) throws Exception {
System.out.println(getName(new WithAnonymousInner() {}.defaultOuter().call()));
System.out.println(getName(WithAnonymousInner.staticOuter().call()));
System.out.println(getName(new WithLocalInner() {}.defaultOuter().call()));
System.out.println(getName(WithLocalInner.staticOuter().call()));
}
static String getName(Class<?> clazz) {
return clazz != null ? clazz.getName() : "null";
}
}
}