blob: 3ce8beb678161ecbfd47a117ba1f8bfb2afa75ad [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.kotlin.lambda.b159688129;
import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar;
import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar;
import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.KotlinTestBase;
import com.android.tools.r8.KotlinTestParameters;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime;
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.nio.file.Path;
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 LambdaSplitByCodeCorrectnessTest extends KotlinTestBase {
private final TestParameters parameters;
private final boolean splitGroup;
@Parameters(name = "{0}, {1}, splitGroup: {2}")
public static List<Object[]> data() {
return buildParameters(
getTestParameters().withDexRuntimes().withAllApiLevels().build(),
getKotlinTestParameters().withAllCompilersAndTargetVersions().build(),
BooleanUtils.values());
}
public LambdaSplitByCodeCorrectnessTest(
TestParameters parameters, KotlinTestParameters kotlinParameters, boolean splitGroup) {
super(kotlinParameters);
this.parameters = parameters;
this.splitGroup = splitGroup;
}
@Test
public void testSplitLambdaGroups() throws Exception {
String PKG_NAME = LambdaSplitByCodeCorrectnessTest.class.getPackage().getName();
String folder = DescriptorUtils.getBinaryNameFromJavaType(PKG_NAME);
CfRuntime cfRuntime =
parameters.isCfRuntime() ? parameters.getRuntime().asCf() : TestRuntime.getCheckedInJdk9();
Path ktClasses =
kotlinc(cfRuntime, kotlinc, targetVersion)
.addSourceFiles(getKotlinFileInTest(folder, "Simple"))
.compile();
testForR8(parameters.getBackend())
.addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc))
.addProgramFiles(ktClasses)
.setMinApi(parameters.getApiLevel())
.addKeepMainRule(PKG_NAME + ".SimpleKt")
.applyIf(
splitGroup,
b ->
b.addOptionsModification(
internalOptions ->
// Setting inliningInstructionAllowance = 1 will force each switch branch to
// contain an invoke instruction to a private method.
internalOptions.inliningInstructionAllowance = 1))
.addHorizontallyMergedClassesInspector(
inspector ->
inspector.assertIsCompleteMergeGroup(
"com.android.tools.r8.kotlin.lambda.b159688129.SimpleKt$main$1",
"com.android.tools.r8.kotlin.lambda.b159688129.SimpleKt$main$2",
"com.android.tools.r8.kotlin.lambda.b159688129.SimpleKt$main$3",
"com.android.tools.r8.kotlin.lambda.b159688129.SimpleKt$main$4",
"com.android.tools.r8.kotlin.lambda.b159688129.SimpleKt$main$5",
"com.android.tools.r8.kotlin.lambda.b159688129.SimpleKt$main$6"))
.allowDiagnosticWarningMessages()
.compile()
.assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.inspect(
codeInspector -> {
ClassSubject mergeTarget =
codeInspector.clazz(
"com.android.tools.r8.kotlin.lambda.b159688129.SimpleKt$main$1");
assertThat(mergeTarget, isPresent());
MethodSubject virtualMethodSubject =
mergeTarget.uniqueMethodThatMatches(
method -> method.isVirtual() && !method.isSynthetic());
assertThat(virtualMethodSubject, isPresent());
int found = 0;
for (FoundMethodSubject directMethodSubject :
mergeTarget.allMethods(x -> x.isPrivate() && !x.isSynthetic())) {
assertThat(virtualMethodSubject, invokesMethod(directMethodSubject));
found++;
}
assertEquals(splitGroup ? 6 : 0, found);
})
.run(parameters.getRuntime(), PKG_NAME + ".SimpleKt")
.assertSuccessWithOutputLines("Hello1", "Hello2", "Hello3", "Hello4", "Hello5", "Hello6");
}
}