| // Copyright (c) 2018, 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; |
| |
| import static org.junit.Assert.assertEquals; |
| |
| import com.android.tools.r8.ByteDataView; |
| import com.android.tools.r8.ClassFileConsumer; |
| import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer; |
| import com.android.tools.r8.CompilationMode; |
| import com.android.tools.r8.DexIndexedConsumer; |
| import com.android.tools.r8.ProgramConsumer; |
| import com.android.tools.r8.R8Command; |
| import com.android.tools.r8.R8Command.Builder; |
| import com.android.tools.r8.TestBase; |
| import com.android.tools.r8.ToolHelper; |
| import com.android.tools.r8.ToolHelper.ProcessResult; |
| import com.android.tools.r8.utils.DescriptorUtils; |
| import com.android.tools.r8.utils.FileUtils; |
| import java.io.IOException; |
| import java.nio.file.Path; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| public class InstantiatedLambdasTestRunner extends TestBase { |
| static final Class CLASS = InstantiatedLambdasTest.class; |
| static final Class[] CLASSES = InstantiatedLambdasTest.CLASSES; |
| |
| private Path inputJar; |
| private ProcessResult runInput; |
| |
| @Before |
| public void writeAndRunInputJar() throws IOException { |
| inputJar = temp.getRoot().toPath().resolve("input.jar"); |
| ArchiveConsumer buildInput = new ArchiveConsumer(inputJar); |
| for (Class clazz : CLASSES) { |
| buildInput.accept( |
| ByteDataView.of(ToolHelper.getClassAsBytes(clazz)), |
| DescriptorUtils.javaTypeToDescriptor(clazz.getName()), |
| null); |
| } |
| buildInput.finished(null); |
| runInput = ToolHelper.runJava(inputJar, CLASS.getCanonicalName()); |
| assertEquals(0, runInput.exitCode); |
| } |
| |
| private Path writeProguardRules(boolean aggressive) throws IOException { |
| Path pgConfig = temp.getRoot().toPath().resolve("keep.txt"); |
| FileUtils.writeTextFile( |
| pgConfig, |
| "-keep public class " + CLASS.getCanonicalName() + " {", |
| " public static void main(...);", |
| "}", |
| aggressive ? "-overloadaggressively" : "# Not overloading aggressively"); |
| return pgConfig; |
| } |
| |
| @Test |
| public void testProguard() throws Exception { |
| buildAndRunProguard("pg.jar", false); |
| } |
| |
| @Test |
| public void testProguardAggressive() throws Exception { |
| buildAndRunProguard("pg-aggressive.jar", true); |
| } |
| |
| @Test |
| public void testCf() throws Exception { |
| buildAndRunCf("cf.zip", false); |
| } |
| |
| @Test |
| public void testCfAggressive() throws Exception { |
| buildAndRunCf("cf-aggressive.zip", true); |
| } |
| |
| @Test |
| public void testDex() throws Exception { |
| buildAndRunDex("dex.zip", false); |
| } |
| |
| @Test |
| public void testDexAggressive() throws Exception { |
| buildAndRunDex("dex-aggressive.zip", true); |
| } |
| |
| private void buildAndRunCf(String outName, boolean aggressive) throws Exception { |
| Path outCf = temp.getRoot().toPath().resolve(outName); |
| build(new ClassFileConsumer.ArchiveConsumer(outCf), aggressive); |
| ProcessResult runCf = ToolHelper.runJava(outCf, CLASS.getCanonicalName()); |
| assertEquals(runInput.toString(), runCf.toString()); |
| } |
| |
| private void buildAndRunDex(String outName, boolean aggressive) throws Exception { |
| Path outDex = temp.getRoot().toPath().resolve(outName); |
| build(new DexIndexedConsumer.ArchiveConsumer(outDex), aggressive); |
| ProcessResult runDex = |
| ToolHelper.runArtNoVerificationErrorsRaw(outDex.toString(), CLASS.getCanonicalName()); |
| assertEquals(runInput.stdout, runDex.stdout); |
| assertEquals(runInput.exitCode, runDex.exitCode); |
| } |
| |
| private void build(ProgramConsumer consumer, boolean aggressive) throws Exception { |
| Builder builder = |
| ToolHelper.addProguardConfigurationConsumer( |
| R8Command.builder(), configuration -> configuration.setPrintMapping(true)) |
| .setMode(CompilationMode.DEBUG) |
| .addLibraryFiles(ToolHelper.getAndroidJar(ToolHelper.getMinApiLevelForDexVm())) |
| .addProgramFiles(inputJar) |
| .setProgramConsumer(consumer) |
| .addProguardConfigurationFiles(writeProguardRules(aggressive)); |
| if (!(consumer instanceof ClassFileConsumer)) { |
| builder.setMinApiLevel(ToolHelper.getMinApiLevelForDexVm().getLevel()); |
| } |
| ToolHelper.runR8(builder.build()); |
| } |
| |
| private void buildAndRunProguard(String outName, boolean aggressive) throws Exception { |
| Path pgConfig = writeProguardRules(aggressive); |
| Path outPg = temp.getRoot().toPath().resolve(outName); |
| ProcessResult proguardResult = |
| ToolHelper.runProguard6Raw( |
| inputJar, outPg, ToolHelper.getJava8RuntimeJar(), pgConfig, null); |
| System.out.println(proguardResult.stdout); |
| if (proguardResult.exitCode != 0) { |
| System.out.println(proguardResult.stderr); |
| } |
| assertEquals(0, proguardResult.exitCode); |
| ProcessResult runPg = ToolHelper.runJava(outPg, CLASS.getCanonicalName()); |
| assertEquals(0, runPg.exitCode); |
| } |
| } |