blob: d7076148d1e45dc0ccea9c13274581db4e4d0d7d [file] [log] [blame]
// 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;
import static com.android.tools.r8.dex.Constants.ANDROID_K_API;
import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DirectoryClassFileProvider;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.OffOrAuto;
import com.android.tools.r8.utils.PreloadedClassFileProvider;
import com.android.tools.r8.utils.ZipUtils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Test;
public class D8LazyRunExamplesAndroidOTest
extends D8IncrementalRunExamplesAndroidOTest {
// Please note that all tool specific markers have been eliminated in the resulting
// dex applications. This allows for byte-wise comparison of the results.
class D8LazyTestRunner extends D8IncrementalTestRunner {
D8LazyTestRunner(String testName, String packageName, String mainClass) {
super(testName, packageName, mainClass);
}
@Override
void addClasspathReference(Path testJarFile, D8Command.Builder builder) {
addClasspathPath(getClassesRoot(testJarFile), builder);
addClasspathPath(getLegacyClassesRoot(testJarFile), builder);
}
private void addClasspathPath(Path location, D8Command.Builder builder) {
builder.addClasspathResourceProvider(
DirectoryClassFileProvider.fromDirectory(location.resolve("..")));
}
@Override
void addLibraryReference(D8Command.Builder builder, Path location) throws IOException {
builder.addLibraryResourceProvider(
PreloadedClassFileProvider.fromArchive(location));
}
}
@Override
D8IncrementalTestRunner test(String testName, String packageName, String mainClass) {
D8IncrementalTestRunner result = new D8LazyTestRunner(testName, packageName, mainClass);
result.withOptionConsumer(options -> options.setMarker(null));
return result;
}
@Test
public void dexPerClassFileWithDesugaringAndFolderClasspath() throws Throwable {
int minAPILevel = ANDROID_K_API;
Path inputFile =
Paths.get(ToolHelper.EXAMPLES_ANDROID_N_BUILD_DIR, "interfacemethods" + JAR_EXTENSION);
Path tmpClassesDir = temp.newFolder().toPath();
ZipUtils.unzip(inputFile.toString(), tmpClassesDir.toFile());
Path androidJar = Paths.get(ToolHelper.getAndroidJar(minAPILevel));
// Build all at once.
AndroidApp fullBuildResult;
{
D8Command command = D8Command.builder()
.setMinApiLevel(minAPILevel)
.addLibraryFiles(androidJar)
.addProgramFiles(inputFile)
.build();
fullBuildResult = ToolHelper.runD8(
command, options -> {
options.interfaceMethodDesugaring = OffOrAuto.Auto;
options.setMarker(null);
});
}
// Build each class individually using tmpClassesDir as classpath for desugaring.
List<Resource> individalDexes = new ArrayList<>();
List<Path> individualClassFiles =
Files.walk(tmpClassesDir)
.filter(classFile -> FileUtils.isClassFile(classFile))
.collect(Collectors.toList());
for (Path classFile : individualClassFiles) {
D8Command.Builder builder =
D8Command.builder()
.setMinApiLevel(minAPILevel)
.addLibraryFiles(androidJar)
.addClasspathFiles(tmpClassesDir)
.addProgramFiles(classFile);
AndroidApp individualResult =
ToolHelper.runD8(
builder.build(),
options -> {
options.interfaceMethodDesugaring = OffOrAuto.Auto;
options.setMarker(null);
});
individalDexes.add(individualResult.getDexProgramResources().get(0));
}
AndroidApp mergedResult = mergeDexResources(minAPILevel, individalDexes);
assertTrue(Arrays.equals(
readFromResource(fullBuildResult.getDexProgramResources().get(0)),
readFromResource(mergedResult.getDexProgramResources().get(0))));
}
private AndroidApp mergeDexResources(int minAPILevel, List<Resource> individalDexes)
throws IOException, CompilationException {
D8Command.Builder builder = D8Command.builder()
.setMinApiLevel(minAPILevel);
for (Resource resource : individalDexes) {
builder.addDexProgramData(readFromResource(resource));
}
AndroidApp mergedResult = ToolHelper.runD8(builder.build(),
options -> options.setMarker(null));
return mergedResult;
}
}