| // 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 com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest; | 
 | import com.android.tools.r8.R8RunArtTestsTest.DexTool; | 
 | import com.android.tools.r8.ToolHelper.DexVm; | 
 | import com.android.tools.r8.errors.Unreachable; | 
 | import java.util.ArrayList; | 
 | import java.util.Arrays; | 
 | import java.util.EnumSet; | 
 | import java.util.List; | 
 | import java.util.stream.Collectors; | 
 |  | 
 | public class TestCondition { | 
 |  | 
 |   enum Runtime { | 
 |     ART_V4_0_4, | 
 |     ART_V4_4_4, | 
 |     ART_V5_1_1, | 
 |     ART_V6_0_1, | 
 |     ART_V7_0_0, | 
 |     ART_V8_1_0, | 
 |     ART_V9_0_0, | 
 |     ART_V10_0_0, | 
 |     ART_V12_0_0, | 
 |     ART_V13_0_0, | 
 |     ART_V14_0_0, | 
 |     ART_DEFAULT, | 
 |     ART_MASTER, | 
 |     JAVA; | 
 |  | 
 |     static final Runtime LOWEST_ART_VERSION = ART_V4_0_4; | 
 |     static final Runtime HIGHEST_ART_VERSION = ART_DEFAULT; | 
 |  | 
 |     static Runtime fromDexVmVersion(DexVm.Version version) { | 
 |       switch (version) { | 
 |         case V4_0_4: | 
 |           return ART_V4_0_4; | 
 |         case V4_4_4: | 
 |           return ART_V4_4_4; | 
 |         case V5_1_1: | 
 |           return ART_V5_1_1; | 
 |         case V6_0_1: | 
 |           return ART_V6_0_1; | 
 |         case V7_0_0: | 
 |           return ART_V7_0_0; | 
 |         case V8_1_0: | 
 |           return ART_V8_1_0; | 
 |         case V9_0_0: | 
 |           return ART_V9_0_0; | 
 |         case V10_0_0: | 
 |           return ART_V10_0_0; | 
 |         case V12_0_0: | 
 |           return ART_V12_0_0; | 
 |         case V13_0_0: | 
 |           return ART_V13_0_0; | 
 |         case V14_0_0: | 
 |           return ART_V14_0_0; | 
 |         case DEFAULT: | 
 |           return ART_DEFAULT; | 
 |         case MASTER: | 
 |           return ART_MASTER; | 
 |         default: | 
 |           throw new Unreachable(); | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   static class ToolSet { | 
 |  | 
 |     final EnumSet<DexTool> set; | 
 |  | 
 |     public ToolSet(EnumSet<DexTool> set) { | 
 |       this.set = set; | 
 |     } | 
 |   } | 
 |  | 
 |   static class CompilerSet { | 
 |  | 
 |     final EnumSet<CompilerUnderTest> set; | 
 |  | 
 |     public CompilerSet(EnumSet<CompilerUnderTest> set) { | 
 |       this.set = set; | 
 |     } | 
 |   } | 
 |  | 
 |   static class RuntimeSet { | 
 |  | 
 |     private final EnumSet<Runtime> set; | 
 |  | 
 |     public RuntimeSet(EnumSet<Runtime> set) { | 
 |       this.set = set; | 
 |     } | 
 |  | 
 |     public static RuntimeSet fromDexVmVersionSet(EnumSet<DexVm.Version> dexVmSet) { | 
 |       List<Runtime> list = new ArrayList<>(dexVmSet.size()); | 
 |       for (DexVm.Version version : dexVmSet) { | 
 |         list.add(Runtime.fromDexVmVersion(version)); | 
 |       } | 
 |       return new RuntimeSet(EnumSet.copyOf(list)); | 
 |     } | 
 |  | 
 |     boolean contains(Runtime runtime) { | 
 |       return set.contains(runtime); | 
 |     } | 
 |   } | 
 |  | 
 |   static class CompilationModeSet { | 
 |  | 
 |     final EnumSet<CompilationMode> set; | 
 |  | 
 |     public CompilationModeSet(EnumSet<CompilationMode> set) { | 
 |       this.set = set; | 
 |     } | 
 |   } | 
 |  | 
 |   public static final CompilerSet D8_COMPILER = | 
 |       compilers(CompilerUnderTest.D8, CompilerUnderTest.D8_AFTER_R8CF); | 
 |   public static final CompilerSet D8_NOT_AFTER_R8CF_COMPILER = compilers(CompilerUnderTest.D8); | 
 |   public static final CompilerSet D8_AFTER_R8CF_COMPILER = | 
 |       compilers(CompilerUnderTest.D8_AFTER_R8CF); | 
 |   // R8_COMPILER refers to R8 both in the standalone setting and after D8 | 
 |   // R8_NOT_AFTER_D8_COMPILER and R8_AFTER_D8_COMPILER refers to the standalone and the combined | 
 |   // settings, respectively | 
 |   public static final CompilerSet R8_COMPILER = | 
 |       compilers( | 
 |           CompilerUnderTest.R8, | 
 |           CompilerUnderTest.R8_AFTER_D8, | 
 |           CompilerUnderTest.D8_AFTER_R8CF, | 
 |           CompilerUnderTest.R8CF); | 
 |   public static final CompilerSet R8DEX_COMPILER = | 
 |       compilers(CompilerUnderTest.R8, CompilerUnderTest.R8_AFTER_D8); | 
 |   public static final CompilerSet R8CF = compilers(CompilerUnderTest.R8CF); | 
 |  | 
 |   public static final CompilationModeSet DEBUG_MODE = | 
 |       new CompilationModeSet(EnumSet.of(CompilationMode.DEBUG)); | 
 |   public static final CompilationModeSet RELEASE_MODE = | 
 |       new CompilationModeSet(EnumSet.of(CompilationMode.RELEASE)); | 
 |  | 
 |   private static final ToolSet ANY_TOOL = new ToolSet(EnumSet.allOf(DexTool.class)); | 
 |   private static final CompilerSet ANY_COMPILER = | 
 |       new CompilerSet(EnumSet.allOf(CompilerUnderTest.class)); | 
 |   private static final RuntimeSet ANY_RUNTIME = new RuntimeSet(EnumSet.allOf(Runtime.class)); | 
 |   private static final RuntimeSet ANY_DEX_VM_RUNTIME = | 
 |       RuntimeSet.fromDexVmVersionSet(EnumSet.allOf(ToolHelper.DexVm.Version.class)); | 
 |   public static final RuntimeSet JAVA_RUNTIME = new RuntimeSet(EnumSet.of(Runtime.JAVA)); | 
 |   private static final CompilationModeSet ANY_MODE = | 
 |       new CompilationModeSet(EnumSet.allOf(CompilationMode.class)); | 
 |  | 
 |   private final EnumSet<DexTool> dexTools; | 
 |   private final EnumSet<CompilerUnderTest> compilers; | 
 |   private final EnumSet<Runtime> runtimes; | 
 |   private final EnumSet<CompilationMode> compilationModes; | 
 |  | 
 |   public TestCondition( | 
 |       EnumSet<DexTool> dexTools, | 
 |       EnumSet<CompilerUnderTest> compilers, | 
 |       EnumSet<Runtime> runtimes, | 
 |       EnumSet<CompilationMode> compilationModes) { | 
 |     this.dexTools = dexTools; | 
 |     this.compilers = compilers; | 
 |     this.runtimes = runtimes; | 
 |     this.compilationModes = compilationModes; | 
 |   } | 
 |  | 
 |   public static ToolSet tools(DexTool... tools) { | 
 |     assert tools.length > 0; | 
 |     return new ToolSet(EnumSet.copyOf(Arrays.asList(tools))); | 
 |   } | 
 |  | 
 |   public static CompilerSet compilers(CompilerUnderTest... compilers) { | 
 |     assert compilers.length > 0; | 
 |     return new CompilerSet(EnumSet.copyOf(Arrays.asList(compilers))); | 
 |   } | 
 |  | 
 |   public static RuntimeSet runtimes(DexVm.Version... runtimes) { | 
 |     assert runtimes.length > 0; | 
 |     return RuntimeSet.fromDexVmVersionSet(EnumSet.copyOf(Arrays.asList(runtimes))); | 
 |   } | 
 |  | 
 |   public static RuntimeSet runtimes(Runtime... runtimes) { | 
 |     assert runtimes.length > 0; | 
 |     return new RuntimeSet(EnumSet.copyOf(Arrays.asList(runtimes))); | 
 |   } | 
 |  | 
 |   public static RuntimeSet runtimesUpTo(DexVm.Version upto) { | 
 |     return RuntimeSet.fromDexVmVersionSet(EnumSet.range(DexVm.Version.first(), upto)); | 
 |   } | 
 |  | 
 |   public static RuntimeSet and(RuntimeSet... sets) { | 
 |     return new RuntimeSet( | 
 |         EnumSet.copyOf( | 
 |             Arrays.stream(sets) | 
 |                 .flatMap(runtimeSet -> runtimeSet.set.stream()) | 
 |                 .collect(Collectors.toSet()))); | 
 |   } | 
 |  | 
 |   public static TestCondition or(TestCondition... conditions) { | 
 |     return new OrTestCondition(conditions); | 
 |   } | 
 |  | 
 |   public static TestCondition match( | 
 |       ToolSet tools, | 
 |       CompilerSet compilers, | 
 |       RuntimeSet runtimes, | 
 |       CompilationModeSet compilationModes) { | 
 |     return new TestCondition(tools.set, compilers.set, runtimes.set, compilationModes.set); | 
 |   } | 
 |  | 
 |   public static TestCondition match(ToolSet tools, CompilerSet compilers, RuntimeSet runtimes) { | 
 |     return match(tools, compilers, runtimes, TestCondition.ANY_MODE); | 
 |   } | 
 |  | 
 |   public static TestCondition any() { | 
 |     return match(TestCondition.ANY_TOOL, TestCondition.ANY_COMPILER, TestCondition.ANY_RUNTIME); | 
 |   } | 
 |  | 
 |   public static TestCondition anyDexVm() { | 
 |     return match( | 
 |         TestCondition.ANY_TOOL, TestCondition.ANY_COMPILER, TestCondition.ANY_DEX_VM_RUNTIME); | 
 |   } | 
 |  | 
 |   public static TestCondition cf() { | 
 |     return match(TestCondition.ANY_TOOL, R8CF, JAVA_RUNTIME); | 
 |   } | 
 |  | 
 |   public static TestCondition match(ToolSet tools) { | 
 |     return match(tools, TestCondition.ANY_COMPILER, TestCondition.ANY_RUNTIME); | 
 |   } | 
 |  | 
 |   public static TestCondition match(ToolSet tools, CompilerSet compilers) { | 
 |     return match(tools, compilers, TestCondition.ANY_RUNTIME); | 
 |   } | 
 |  | 
 |   public static TestCondition match(ToolSet tools, RuntimeSet runtimes) { | 
 |     return match(tools, TestCondition.ANY_COMPILER, runtimes); | 
 |   } | 
 |  | 
 |   public static TestCondition match(CompilerSet compilers) { | 
 |     return match(TestCondition.ANY_TOOL, compilers, TestCondition.ANY_RUNTIME); | 
 |   } | 
 |  | 
 |   public static TestCondition match(CompilerSet compilers, CompilationModeSet compilationModes) { | 
 |     return match(TestCondition.ANY_TOOL, compilers, TestCondition.ANY_RUNTIME, compilationModes); | 
 |   } | 
 |  | 
 |   public static TestCondition match(CompilerSet compilers, RuntimeSet runtimes) { | 
 |     return match(TestCondition.ANY_TOOL, compilers, runtimes); | 
 |   } | 
 |  | 
 |   public static TestCondition match(RuntimeSet runtimes) { | 
 |     return match(TestCondition.ANY_TOOL, TestCondition.ANY_COMPILER, runtimes); | 
 |   } | 
 |  | 
 |   public boolean test( | 
 |       DexTool dexTool, | 
 |       CompilerUnderTest compilerUnderTest, | 
 |       Runtime runtime, | 
 |       CompilationMode compilationMode) { | 
 |     return dexTools.contains(dexTool) | 
 |         && compilers.contains(compilerUnderTest) | 
 |         && runtimes.contains(runtime) | 
 |         && compilationModes.contains(compilationMode); | 
 |   } | 
 |  | 
 |   public boolean test( | 
 |       DexTool dexTool, | 
 |       CompilerUnderTest compilerUnderTest, | 
 |       DexVm.Version version, | 
 |       CompilationMode compilationMode) { | 
 |     return test(dexTool, compilerUnderTest, Runtime.fromDexVmVersion(version), compilationMode); | 
 |   } | 
 |  | 
 |   public static class OrTestCondition extends TestCondition { | 
 |  | 
 |     private final TestCondition[] conditions; | 
 |  | 
 |     public OrTestCondition(TestCondition[] conditions) { | 
 |       super(null, null, null, null); | 
 |       this.conditions = conditions; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public boolean test( | 
 |         DexTool dexTool, | 
 |         CompilerUnderTest compilerUnderTest, | 
 |         Runtime runtime, | 
 |         CompilationMode compilationMode) { | 
 |       for (TestCondition condition : conditions) { | 
 |         if (condition.test(dexTool, compilerUnderTest, runtime, compilationMode)) { | 
 |           return true; | 
 |         } | 
 |       } | 
 |       return false; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public boolean test( | 
 |         DexTool dexTool, | 
 |         CompilerUnderTest compilerUnderTest, | 
 |         DexVm.Version version, | 
 |         CompilationMode compilationMode) { | 
 |       for (TestCondition condition : conditions) { | 
 |         if (condition.test(dexTool, compilerUnderTest, version, compilationMode)) { | 
 |           return true; | 
 |         } | 
 |       } | 
 |       return false; | 
 |     } | 
 |   } | 
 | } |