| // 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); | 
 |   } | 
 | } |