blob: 0636a50a6cc62705f12e4ae1fe7965a176283a5d [file] [log] [blame]
// Copyright (c) 2021, 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.repackage;
import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
import static com.android.tools.r8.shaking.ProguardConfigurationParser.REPACKAGE_CLASSES;
import static org.hamcrest.CoreMatchers.containsString;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableList;
import java.util.List;
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 RepackageParameterSyntheticOutlineTest extends RepackageTestBase {
private final String NEW_DESCRIPTOR = "Lfoo/ClassWithCodeToBeOutlined;";
private final String[] EXPECTED =
new String[] {"Param::testParam", "Return::print", "Param::testParam", "Return::print"};
@Parameters(name = "{1}, kind: {0}")
public static List<Object[]> data() {
return buildParameters(
ImmutableList.of(REPACKAGE_CLASSES), // Repackage will use foo as the package name.
getTestParameters().withDexRuntimes().withAllApiLevels().build());
}
public RepackageParameterSyntheticOutlineTest(
String flattenPackageHierarchyOrRepackageClasses, TestParameters parameters) {
super(flattenPackageHierarchyOrRepackageClasses, parameters);
}
@Test
public void testRuntime() throws Exception {
testForRuntime(parameters)
.addProgramClasses(Param.class, Return.class)
.addProgramClassFileData(
rewrittenPackageForClassWithCodeToBeOutlined(),
rewrittenMainWithMethodReferencesToCodeToBeOutlined())
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLines(EXPECTED);
}
@Test(expected = CompilationFailedException.class)
public void testR8() throws Exception {
testForR8(parameters.getBackend())
.addProgramClasses(Param.class, Return.class)
.addProgramClassFileData(
rewrittenPackageForClassWithCodeToBeOutlined(),
rewrittenMainWithMethodReferencesToCodeToBeOutlined())
.addKeepMainRule(Main.class)
.addKeepClassRulesWithAllowObfuscation(Param.class, Return.class)
.setMinApi(parameters.getApiLevel())
.enableInliningAnnotations()
.addOptionsModification(
options -> {
options.outline.minSize = 2;
options.outline.threshold = 2;
})
.apply(this::configureRepackaging)
.addKeepPackageNamesRule("bar**")
.compileWithExpectedDiagnostics(
diagnostics -> {
// TODO(b/180092122): This should not fail.
diagnostics.assertErrorsMatch(
diagnosticMessage(
containsString("The synthetic method reference should have moved")));
});
}
private byte[] rewrittenPackageForClassWithCodeToBeOutlined() throws Exception {
return transformer(ClassWithCodeToBeOutlined.class)
.setClassDescriptor(NEW_DESCRIPTOR)
.transform();
}
private byte[] rewrittenMainWithMethodReferencesToCodeToBeOutlined() throws Exception {
return transformer(Main.class)
.replaceClassDescriptorInMethodInstructions(
DescriptorUtils.javaTypeToDescriptor(ClassWithCodeToBeOutlined.class.getTypeName()),
NEW_DESCRIPTOR)
.transform();
}
// Will be renamed by repackaging
public static class Param {
@NeverInline
public void testParam() {
System.out.println("Param::testParam");
}
@NeverInline
public Return getReturn() {
return new Return();
}
}
// Will be renamed by repackaging
public static class Return {
public void print() {
System.out.println("Return::print");
}
}
// Renamed to baz.ClassWithCodeToBeOutlined such that we can keep this package name.
public static class ClassWithCodeToBeOutlined {
@NeverInline
public static Return foo(Param param) {
param.testParam();
return param.getReturn();
}
@NeverInline
public static Return bar(Param param) {
param.testParam();
return param.getReturn();
}
}
public static class Main {
public static void main(String[] args) {
Param param = new Param();
ClassWithCodeToBeOutlined.foo(param).print();
ClassWithCodeToBeOutlined.bar(param).print();
}
}
}