blob: cc1f2410dbb5ee3bf61875b80ba2afe878c2bf6a [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.shaking.attributes;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8TestBuilder;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
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 KeepEnclosingMethodForKeptMethodTest extends TestBase {
private final TestParameters parameters;
private final String[] EXPECTED = {
"null",
"class com.android.tools.r8.shaking.attributes.KeepEnclosingMethodForKeptMethodTest"
+ "$KeptClass",
"public static com.android.tools.r8.shaking.attributes.KeepEnclosingMethodForKeptMethodTest$I "
+ "com.android.tools.r8.shaking.attributes.KeepEnclosingMethodForKeptMethodTest$KeptClass.enclosingFromKeptMethod()",
"public"
+ " com.android.tools.r8.shaking.attributes.KeepEnclosingMethodForKeptMethodTest$KeptClass()"
};
private final String[] R8_OUTPUT = {
"null",
"class com.android.tools.r8.shaking.attributes.KeepEnclosingMethodForKeptMethodTest"
+ "$KeptClass",
"null",
"null"
};
@Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withAllRuntimesAndApiLevels().build();
}
public KeepEnclosingMethodForKeptMethodTest(TestParameters parameters) {
this.parameters = parameters;
}
@Test
public void testRuntime() throws Exception {
testForRuntime(parameters)
.addInnerClasses(KeptClass.class)
.addProgramClassFileData(
transformer(I.class).removeInnerClasses().transform(),
transformer(KeptClass.class).removeInnerClasses().transform())
.run(parameters.getRuntime(), KeptClass.class)
.assertSuccessWithOutputLines(EXPECTED);
}
@Test
public void testR8Full() throws Exception {
// TODO(b/171194649): This should output EXPECTED.
runTest(testForR8(parameters.getBackend())).assertSuccessWithOutputLines(R8_OUTPUT);
}
@Test
public void testR8Compat() throws Exception {
runTest(testForR8Compat(parameters.getBackend())).assertSuccessWithOutputLines(EXPECTED);
}
private R8TestRunResult runTest(R8TestBuilder<?> testBuilder) throws Exception {
return testBuilder
.addInnerClasses(KeptClass.class)
.addProgramClassFileData(
transformer(I.class).removeInnerClasses().transform(),
transformer(KeptClass.class).removeInnerClasses().transform())
.addKeepClassRules(I.class)
.addKeepAttributeInnerClassesAndEnclosingMethod()
.addKeepMainRule(KeptClass.class)
.addKeepClassAndMembersRules(KeptClass.class)
.setMinApi(parameters.getApiLevel())
.enableInliningAnnotations()
.run(parameters.getRuntime(), KeptClass.class);
}
public interface I {
void foo();
}
public static class KeptClass {
static I staticField =
new I() {
@Override
public void foo() {
System.out.println(this.getClass().getEnclosingConstructor());
System.out.println(this.getClass().getEnclosingClass());
}
};
private I instanceField;
public KeptClass() {
instanceField =
new I() {
@Override
public void foo() {
System.out.println(this.getClass().getEnclosingConstructor());
}
};
}
public static void main(String[] args) {
staticField.foo();
enclosingFromKeptMethod().foo();
new KeptClass().instanceField.foo();
}
@NeverInline
public static I enclosingFromKeptMethod() {
return new I() {
@Override
public void foo() {
System.out.println(this.getClass().getEnclosingMethod());
}
};
}
}
}