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