blob: c126083d3a451f628ab2faa151c3205d07642ac1 [file] [log] [blame]
// 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;
import com.android.tools.r8.D8Command.Builder;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.InternalCompilerError;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
public class D8IncrementalRunExamplesJava9Test extends RunExamplesJava9Test<D8Command.Builder> {
class D8TestRunner extends TestRunner<D8TestRunner> {
D8TestRunner(String testName, String packageName, String mainClass) {
super(testName, packageName, mainClass);
}
@Override
D8TestRunner withMinApiLevel(int minApiLevel) {
return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel));
}
@Override
void build(Path inputFile, Path out) throws Throwable {
List<String> dexFiles = compileIncremental(inputFile);
assert !dexFiles.isEmpty();
mergeDexFiles(dexFiles, out);
}
private List<String> compileIncremental(Path inputFile) throws Throwable {
Builder builder = D8Command.builder();
for (UnaryOperator<Builder> transformation : builderTransformations) {
builder = transformation.apply(builder);
}
// Root to incremental output
Path incrementalOutput = temp.getRoot().toPath().resolve("incremental");
builder
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
.addProgramFiles(inputFile)
.setOutput(incrementalOutput, OutputMode.DexFilePerClassFile);
ToolHelper.runD8(builder, this::combinedOptionConsumer);
return collectDexFiles(incrementalOutput);
}
private void mergeDexFiles(List<String> dexFiles, Path out) throws Throwable {
Builder builder = D8Command.builder();
builder.addProgramFiles(
dexFiles.stream().map(str -> Paths.get(str)).collect(Collectors.toList()));
for (UnaryOperator<Builder> transformation : builderTransformations) {
builder = transformation.apply(builder);
}
builder.setOutput(out, OutputMode.DexIndexed);
try {
AndroidApp app = ToolHelper.runD8(builder, this::combinedOptionConsumer);
assert app.getDexProgramResourcesForTesting().size() == 1;
} catch (Unimplemented | CompilationError | InternalCompilerError re) {
throw re;
} catch (RuntimeException re) {
throw re.getCause() == null ? re : re.getCause();
}
}
private List<String> collectDexFiles(Path incrementalOutput) {
List<String> result = new ArrayList<>();
collectDexFiles(incrementalOutput, result);
Collections.sort(result);
return result;
}
private void collectDexFiles(Path dir, List<String> result) {
if (Files.exists(dir)) {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path entry : stream) {
if (Files.isDirectory(entry)) {
collectDexFiles(entry, result);
} else {
result.add(entry.toString());
}
}
} catch (IOException x) {
throw new AssertionError(x);
}
}
}
@Override
D8TestRunner self() {
return this;
}
}
@Override
D8TestRunner test(String testName, String packageName, String mainClass) {
return new D8TestRunner(testName, packageName, mainClass);
}
}