| // 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.ClassFileConsumer.ArchiveConsumer; | |
| import com.android.tools.r8.D8Command.Builder; | |
| import com.android.tools.r8.TestBase.Backend; | |
| import com.android.tools.r8.ToolHelper.ProcessResult; | |
| import com.android.tools.r8.errors.Unimplemented; | |
| import com.android.tools.r8.utils.AndroidApp; | |
| import com.android.tools.r8.utils.InternalOptions; | |
| import com.android.tools.r8.utils.ListUtils; | |
| import com.android.tools.r8.utils.StringUtils; | |
| import java.io.IOException; | |
| import java.nio.file.Path; | |
| import java.util.ArrayList; | |
| import java.util.Collection; | |
| import java.util.List; | |
| import java.util.function.Consumer; | |
| import java.util.function.Supplier; | |
| import java.util.stream.Collectors; | |
| // The type arguments D8Command, Builder is not relevant for running DX. | |
| public class DXTestBuilder | |
| extends TestCompilerBuilder< | |
| D8Command, Builder, DXTestCompileResult, DXTestRunResult, DXTestBuilder> { | |
| // Ordered list of injar entries. | |
| private List<Path> injars = new ArrayList<>(); | |
| private DXTestBuilder(TestState state) { | |
| super(state, D8Command.builder(), Backend.DEX); | |
| } | |
| public static DXTestBuilder create(TestState state) { | |
| return new DXTestBuilder(state); | |
| } | |
| @Override | |
| DXTestBuilder self() { | |
| return this; | |
| } | |
| @Override | |
| DXTestCompileResult internalCompile( | |
| Builder builder, Consumer<InternalOptions> optionsConsumer, Supplier<AndroidApp> app) | |
| throws CompilationFailedException { | |
| assert !libraryDesugaringTestConfiguration.isEnabled(); | |
| try { | |
| Path dxOutputFolder = getState().getNewTempFolder(); | |
| Path outJar = dxOutputFolder.resolve("output.jar"); | |
| List<String> args = new ArrayList<>(); | |
| args.add("--min-sdk-version=" + getMinApiLevel()); | |
| args.add("--output=" + outJar.toString()); | |
| args.addAll(injars.stream().map(Path::toString).collect(Collectors.toList())); | |
| ProcessResult result = | |
| ToolHelper.runProcess( | |
| ToolHelper.createProcessBuilderForRunningDx(args.toArray(StringUtils.EMPTY_ARRAY)), | |
| getStdoutForTesting()); | |
| if (result.exitCode != 0) { | |
| throw new CompilationFailedException(result.toString()); | |
| } | |
| return new DXTestCompileResult( | |
| getState(), AndroidApp.builder().addProgramFile(outJar).build(), getMinApiLevel()); | |
| } catch (IOException e) { | |
| throw new CompilationFailedException(e); | |
| } | |
| } | |
| @Override | |
| public DXTestBuilder addClasspathClasses(Collection<Class<?>> classes) { | |
| throw new Unimplemented("No support for adding classpath data directly"); | |
| } | |
| @Override | |
| public DXTestBuilder addClasspathFiles(Collection<Path> files) { | |
| throw new Unimplemented("No support for adding classpath data directly"); | |
| } | |
| @Override | |
| public DXTestBuilder addProgramClasses(Collection<Class<?>> classes) { | |
| return addProgramClassFileData( | |
| ListUtils.map( | |
| classes, | |
| c -> { | |
| try { | |
| return ToolHelper.getClassAsBytes(c); | |
| } catch (IOException e) { | |
| throw new RuntimeException(e); | |
| } | |
| })); | |
| } | |
| @Override | |
| public DXTestBuilder addProgramClassFileData(Collection<byte[]> classes) { | |
| try { | |
| Path out = getState().getNewTempFolder().resolve("out.jar"); | |
| ArchiveConsumer consumer = new ArchiveConsumer(out); | |
| for (byte[] clazz : classes) { | |
| String descriptor = TestBase.extractClassDescriptor(clazz); | |
| consumer.accept(ByteDataView.of(clazz), descriptor, null); | |
| } | |
| consumer.finished(null); | |
| addProgramFiles(out); | |
| return self(); | |
| } catch (IOException e) { | |
| throw new RuntimeException(e); | |
| } | |
| } | |
| @Override | |
| public DXTestBuilder addProgramDexFileData(Collection<byte[]> data) { | |
| throw new Unimplemented("No support for adding dex file data directly"); | |
| } | |
| @Override | |
| public DXTestBuilder addProgramFiles(Collection<Path> files) { | |
| injars.addAll(files); | |
| return self(); | |
| } | |
| } |