blob: 04d84e40c3a6a0364868920ced26bc5c2fefa39b [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.jasmin;
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.R8;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.ProguardRuleParserException;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.OutputMode;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import jasmin.ClassFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
public class JasminTestBase {
@Rule
public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();
protected ProcessResult runOnJavaRaw(JasminBuilder builder, String main) throws Exception {
File out = temp.newFolder("classes");
for (ClassBuilder clazz : builder.getClasses()) {
ClassFile file = new ClassFile();
file.readJasmin(new StringReader(clazz.toString()), clazz.name, true);
Path path = out.toPath().resolve(clazz.name + ".class");
Files.createDirectories(path.getParent());
file.write(new FileOutputStream(path.toFile()));
}
return ToolHelper.runJava(ImmutableList.of(out.getPath()), main);
}
protected String runOnJava(JasminBuilder builder, String main) throws Exception {
ProcessResult result = runOnJavaRaw(builder, main);
if (result.exitCode != 0) {
System.out.println("Std out:");
System.out.println(result.stdout);
System.out.println("Std err:");
System.out.println(result.stderr);
assertEquals(0, result.exitCode);
}
return result.stdout;
}
protected String runOnArt(JasminBuilder builder, String main) throws Exception {
// TODO(zerny): Make the compiler depend on tool flag?
return runOnArtR8(builder, main, new InternalOptions());
}
protected AndroidApp compileWithD8(JasminBuilder builder) throws Exception {
return ToolHelper.runD8(builder.build());
}
protected String runOnArtD8(JasminBuilder builder, String main) throws Exception {
return runOnArt(compileWithD8(builder), main);
}
protected String runOnArtR8(JasminBuilder builder, String main, InternalOptions options)
throws Exception {
DexApplication app = builder.read();
app = process(app, options);
AppInfo info = new AppInfo(app);
AndroidApp outputApp =
R8.writeApplication(
Executors.newSingleThreadExecutor(),
app,
info,
null,
NamingLens.getIdentityLens(),
null,
null,
options);
return runOnArt(outputApp, main);
}
private ProcessResult runDx(JasminBuilder builder, File classes, Path dex) throws Exception {
for (ClassBuilder clazz : builder.getClasses()) {
ClassFile file = new ClassFile();
file.readJasmin(new StringReader(clazz.toString()), clazz.name, true);
file.write(new FileOutputStream(classes.toPath().resolve(clazz.name + ".class").toFile()));
}
List<String> args = new ArrayList<>();
args.add("--output=" + dex.toString());
args.add(classes.toString());
System.out.println("running: dx " + StringUtils.join(args, " "));
return ToolHelper.runDX(args.toArray(new String[args.size()]));
}
protected ProcessResult runOnArtDxRaw(JasminBuilder builder) throws Exception {
return runDx(builder, temp.newFolder("classes_for_dx"),
temp.getRoot().toPath().resolve("classes.dex"));
}
protected String runOnArtDx(JasminBuilder builder, String main) throws Exception {
Path dex = temp.getRoot().toPath().resolve("classes.dex");
ProcessResult result = runDx(builder, temp.newFolder("classes_for_dx"), dex);
if (result.exitCode != 0) {
System.out.println("Std out:");
System.out.println(result.stdout);
System.out.println("Std err:");
System.out.println(result.stderr);
assertEquals(0, result.exitCode);
}
return ToolHelper.runArtNoVerificationErrors(dex.toString(), main);
}
protected String runOnArt(AndroidApp app, String main) throws IOException {
Path out = temp.getRoot().toPath().resolve("out.zip");
app.writeToZip(out, OutputMode.Indexed);
return ToolHelper.runArtNoVerificationErrors(ImmutableList.of(out.toString()), main, null);
}
protected static DexApplication process(DexApplication app, InternalOptions options)
throws IOException, ProguardRuleParserException, ExecutionException {
return ToolHelper.optimizeWithR8(app, new AppInfoWithSubtyping(app), options);
}
}