blob: 78bbcf339c561e556f2040f333bec3b1aa941a04 [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.utils.FileUtils.JAR_EXTENSION;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.D8Command.Builder;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.OffOrAuto;
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(Builder builder, Path location) throws IOException {
builder.addLibraryResourceProvider(new ArchiveClassFileProvider(location));
}
@Override
D8LazyTestRunner self() {
return this;
}
}
@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 {
AndroidApiLevel minAPILevel = AndroidApiLevel.K;
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 = ToolHelper.getAndroidJar(minAPILevel);
// Build all at once.
AndroidApp fullBuildResult;
{
D8Command.Builder command =
D8Command.builder()
.setMinApiLevel(minAPILevel.getLevel())
.addLibraryFiles(androidJar)
.addProgramFiles(inputFile);
fullBuildResult = ToolHelper.runD8(
command, options -> {
options.interfaceMethodDesugaring = OffOrAuto.Auto;
options.setMarker(null);
});
}
// Build each class individually using tmpClassesDir as classpath for desugaring.
List<ProgramResource> individalDexes = new ArrayList<>();
List<Path> individualClassFiles =
Files.walk(tmpClassesDir).filter(FileUtils::isClassFile).collect(Collectors.toList());
for (Path classFile : individualClassFiles) {
D8Command.Builder builder =
D8Command.builder()
.setMinApiLevel(minAPILevel.getLevel())
.addLibraryFiles(androidJar)
.addClasspathFiles(tmpClassesDir)
.addProgramFiles(classFile);
AndroidApp individualResult =
ToolHelper.runD8(
builder,
options -> {
options.interfaceMethodDesugaring = OffOrAuto.Auto;
options.setMarker(null);
});
individalDexes.add(individualResult.getDexProgramResourcesForTesting().get(0));
}
AndroidApp mergedResult = mergeDexResources(minAPILevel.getLevel(), individalDexes);
assertTrue(Arrays.equals(
readResource(fullBuildResult.getDexProgramResourcesForTesting().get(0)),
readResource(mergedResult.getDexProgramResourcesForTesting().get(0))));
}
private AndroidApp mergeDexResources(int minAPILevel, List<ProgramResource> individalDexes)
throws IOException, CompilationFailedException, ResourceException {
D8Command.Builder builder = D8Command.builder()
.setMinApiLevel(minAPILevel);
for (ProgramResource resource : individalDexes) {
builder.addDexProgramData(readResource(resource), resource.getOrigin());
}
AndroidApp mergedResult = ToolHelper.runD8(builder, options -> options.setMarker(null));
return mergedResult;
}
}