blob: a1e32b4177f44433ad1302f203b3b6411f602d89 [file] [log] [blame]
// Copyright (c) 2019, 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.cf.bootstrap;
import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
import com.android.tools.r8.internal.CompilationTestBase;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableList;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import org.junit.Ignore;
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 KotlinCompilerTreeShakingTest extends CompilationTestBase {
private static final String PKG_NAME = KotlinCompilerTreeShakingTest.class.getPackage().getName();
private static final Path HELLO_KT =
Paths.get(
ToolHelper.TESTS_DIR,
"java",
DescriptorUtils.getBinaryNameFromJavaType(PKG_NAME),
"Hello.kt");
private static final int MAX_SIZE = (int) (31361268 * 0.4);
private TestParameters parameters;
@Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withCfRuntimes().build();
}
public KotlinCompilerTreeShakingTest(TestParameters parameters) {
this.parameters = parameters;
}
@Test
public void testForRuntime() throws Exception {
// Compile Hello.kt and make sure it works as expected.
Path classPathBefore =
kotlinc(parameters.getRuntime().asCf(), KOTLINC, KotlinTargetVersion.JAVA_8)
.addSourceFiles(HELLO_KT)
.setOutputPath(temp.newFolder().toPath())
.compile();
testForJvm()
.addRunClasspathFiles(ToolHelper.getKotlinStdlibJar())
.addClasspath(classPathBefore)
.run(parameters.getRuntime(), PKG_NAME + ".HelloKt")
.assertSuccessWithOutputLines("I'm Woody. Howdy, howdy, howdy.");
}
@Ignore(
"b/136457753: assertion error in static class merger; "
+ "b/144877828: assertion error in method naming state during interface method renaming; "
+ "b/144859533: umbrella"
)
@Test
public void test() throws Exception {
List<Path> libs =
ImmutableList.of(
ToolHelper.getKotlinStdlibJar(),
ToolHelper.getKotlinReflectJar(),
Paths.get(ToolHelper.KT_SCRIPT_RT));
// Process kotlin-compiler.jar.
Path r8ProcessedKotlinc =
testForR8(parameters.getBackend())
.addLibraryFiles(libs)
.addLibraryFiles(ToolHelper.getJava8RuntimeJar())
.addProgramFiles(Paths.get(ToolHelper.KT_COMPILER))
.addKeepAttributes("*Annotation*")
.addKeepClassAndMembersRules(ToolHelper.K2JVMCompiler)
.addKeepClassAndMembersRules("**.K2JVMCompilerArguments")
.addKeepClassAndMembersRules("**.*Argument*")
.addKeepClassAndMembersRules("**.Freezable")
.addKeepRules(
"-keepclassmembers class * {",
" *** parseCommandLineArguments(...);",
"}"
)
.addKeepRules(
"-keepclassmembers,allowoptimization enum * {",
" public static **[] values();",
" public static ** valueOf(java.lang.String);",
"}")
.addOptionsModification(o -> {
// Ignore com.sun.tools.javac.main.JavaCompiler and others
// Resulting jar may not be able to deal with .java source files, though.
o.ignoreMissingClasses = true;
// b/144861100: invoke-static on interface is allowed up to JDK 8.
o.testing.allowInvokeErrors = true;
})
.compile()
.writeToZip();
// Copy libraries used by kotlin-compiler.jar so that Preloader can load them.
Path dir = r8ProcessedKotlinc.getParent();
for (Path lib : libs) {
Path newLib = dir.resolve(lib.getFileName());
Files.copy(lib, newLib, REPLACE_EXISTING);
}
// TODO(b/144859533): passing `dir` as -kotlin-home.
// Compile Hello.kt again with r8-processed kotlin-compiler.jar
Path classPathAfter =
kotlinc(
parameters.getRuntime().asCf(),
new KotlinCompiler("r8ProcessedKotlinc", r8ProcessedKotlinc),
KotlinTargetVersion.JAVA_8)
.addSourceFiles(HELLO_KT)
.setOutputPath(temp.newFolder().toPath())
.compile();
testForJvm()
.addRunClasspathFiles(ToolHelper.getKotlinStdlibJar())
.addClasspath(classPathAfter)
.run(parameters.getRuntime(), PKG_NAME + ".HelloKt")
.assertSuccessWithOutputLines("I'm Woody. Howdy, howdy, howdy.");
int size = applicationSize(AndroidApp.builder().addProgramFile(r8ProcessedKotlinc).build());
assertTrue(size <= MAX_SIZE);
}
}