| // Copyright (c) 2017, 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 com.android.tools.r8.ToolHelper.EXAMPLES_BUILD_DIR; |
| import static com.android.tools.r8.ToolHelper.EXAMPLES_DIR; |
| |
| import com.android.tools.r8.CompilationFailedException; |
| import com.android.tools.r8.Diagnostic; |
| import com.android.tools.r8.DiagnosticsHandler; |
| import com.android.tools.r8.OutputMode; |
| import com.android.tools.r8.R8; |
| import com.android.tools.r8.R8Command; |
| import com.android.tools.r8.ToolHelper; |
| import java.io.BufferedReader; |
| import java.io.PrintStream; |
| import java.io.StringReader; |
| import java.nio.charset.StandardCharsets; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.stream.Collectors; |
| import java.util.stream.Stream; |
| import org.junit.Assert; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.ExpectedException; |
| import org.junit.rules.TemporaryFolder; |
| |
| public class TreeShakingSpecificTest { |
| private static final String VALID_PROGUARD_DIR = "src/test/proguard/valid/"; |
| |
| @Rule |
| public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest(); |
| |
| @Rule |
| public ExpectedException thrown = ExpectedException.none(); |
| |
| @Test |
| public void testIgnoreWarnings() throws Exception { |
| // Generate R8 processed version without library option. |
| Path out = temp.getRoot().toPath(); |
| String test = "shaking2"; |
| Path originalDex = Paths.get(EXAMPLES_BUILD_DIR, test, "classes.dex"); |
| Path keepRules = Paths.get(EXAMPLES_DIR, test, "keep-rules.txt"); |
| Path ignoreWarnings = Paths.get(VALID_PROGUARD_DIR, "ignorewarnings.flags"); |
| R8Command.Builder builder = R8Command.builder() |
| .setOutput(out, OutputMode.DexIndexed) |
| .addProguardConfigurationFiles(keepRules, ignoreWarnings); |
| ToolHelper.getAppBuilder(builder).addProgramFiles(originalDex); |
| R8.run(builder.build()); |
| } |
| |
| @Test(expected = CompilationFailedException.class) |
| public void testMissingLibrary() throws Exception { |
| // Generate R8 processed version without library option. |
| Path out = temp.getRoot().toPath(); |
| String test = "shaking2"; |
| Path originalDex = Paths.get(EXAMPLES_BUILD_DIR, test, "classes.dex"); |
| Path keepRules = Paths.get(EXAMPLES_DIR, test, "keep-rules.txt"); |
| DiagnosticsHandler handler = new DiagnosticsHandler() { |
| @Override |
| public void error(Diagnostic error) { |
| if (!error.getDiagnosticMessage().contains("library classes are missing")) { |
| throw new RuntimeException("Unexpected compilation error"); |
| } |
| } |
| }; |
| R8Command.Builder builder = R8Command.builder(handler) |
| .setOutput(out, OutputMode.DexIndexed) |
| .addProguardConfigurationFiles(keepRules); |
| ToolHelper.getAppBuilder(builder).addProgramFiles(originalDex); |
| R8.run(builder.build()); |
| } |
| |
| @Test |
| public void testPrintMapping() throws Exception { |
| // Generate R8 processed version without library option. |
| String test = "shaking1"; |
| Path out = temp.getRoot().toPath(); |
| Path originalDex = Paths.get(EXAMPLES_BUILD_DIR, test, "classes.dex"); |
| Path keepRules = Paths.get(EXAMPLES_DIR, test, "keep-rules.txt"); |
| |
| // Create a flags file in temp dir requesting dump of the mapping. |
| // The mapping file will be created alongside the flags file in temp dir. |
| Path printMapping = out.resolve("printmapping.flags"); |
| try (PrintStream mapping = new PrintStream(printMapping.toFile())) { |
| mapping.println("-printmapping mapping.txt"); |
| } |
| |
| R8Command.Builder builder = R8Command.builder() |
| .setOutput(out, OutputMode.DexIndexed) |
| .addProguardConfigurationFiles(keepRules, printMapping); |
| ToolHelper.getAppBuilder(builder).addProgramFiles(originalDex); |
| // Turn off inlining, as we want the mapping that is printed to be stable. |
| ToolHelper.runR8(builder.build(), options -> options.enableInlining = false); |
| |
| Path outputmapping = out.resolve("mapping.txt"); |
| // Remove comments. |
| String actualMapping = |
| Stream.of(new String(Files.readAllBytes(outputmapping), StandardCharsets.UTF_8).split("\n")) |
| .filter(line -> !line.startsWith("#")) |
| .collect(Collectors.joining("\n")); |
| String refMapping = new String(Files.readAllBytes( |
| Paths.get(EXAMPLES_DIR, "shaking1", "print-mapping.ref")), StandardCharsets.UTF_8); |
| Assert.assertEquals(sorted(refMapping), sorted(actualMapping)); |
| } |
| |
| private static String sorted(String str) { |
| return new BufferedReader(new StringReader(str)) |
| .lines().sorted().filter(s -> !s.isEmpty()).collect(Collectors.joining("\n")); |
| } |
| } |