aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYohann Roussel <yroussel@google.com>2017-09-04 21:58:17 +0000
committerYohann Roussel <yroussel@google.com>2017-09-04 21:58:17 +0000
commit4f3a8b35a1fa10972497d3a071be00d2237ce42c (patch)
tree5aa79d000b667950499ba3d2c538b3615fd9400c
parent9d00aca8b5a5e6e4a589afeb683de26c58048a1c (diff)
downloadr8-4f3a8b35a1fa10972497d3a071be00d2237ce42c.tar.gz
Revert "Loosen desugaring constraints"
This reverts commit 9d00aca8b5a5e6e4a589afeb683de26c58048a1c. Change-Id: I2b3f24c8291e24400ddfd99ba7f7fd2cd11a30fa
-rw-r--r--src/main/java/com/android/tools/r8/D8Command.java2
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java143
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/DefaultMethodsHelper.java14
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java84
-rw-r--r--src/main/java/com/android/tools/r8/utils/InternalOptions.java4
-rw-r--r--src/test/examplesAndroidO/desugaringwithandroidjar25/DefaultMethodInAndroidJar25.java100
-rw-r--r--src/test/examplesAndroidO/desugaringwithandroidjar25/StaticMethodInAndroidJar25.java17
-rw-r--r--src/test/examplesAndroidO/desugaringwithmissingclasslib1/A.java10
-rw-r--r--src/test/examplesAndroidO/desugaringwithmissingclasslib2/B.java13
-rw-r--r--src/test/examplesAndroidO/desugaringwithmissingclasslib3/C.java9
-rw-r--r--src/test/examplesAndroidO/desugaringwithmissingclasstest1/ImplementMethodsWithDefault.java10
-rw-r--r--src/test/examplesAndroidO/desugaringwithmissingclasstest1/Main.java21
-rw-r--r--src/test/examplesAndroidO/desugaringwithmissingclasstest2/ImplementMethodsWithDefault.java10
-rw-r--r--src/test/examplesAndroidO/desugaringwithmissingclasstest2/Main.java21
-rw-r--r--src/test/examplesAndroidO/desugaringwithmissingclasstest3/ImplementMethodsWithDefault.java18
-rw-r--r--src/test/examplesAndroidO/desugaringwithmissingclasstest3/Main.java32
-rw-r--r--src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java10
-rw-r--r--src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java5
-rw-r--r--src/test/java/com/android/tools/r8/D8NonLazyRunExamplesAndroidOTest.java8
-rw-r--r--src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java384
-rw-r--r--src/test/java/com/android/tools/r8/R8RunArtTestsTest.java26
-rw-r--r--src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java13
-rw-r--r--src/test/java/com/android/tools/r8/RunExamplesAndroidNTest.java4
-rw-r--r--src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java145
-rw-r--r--src/test/java/com/android/tools/r8/ToolHelper.java4
-rw-r--r--src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java22
26 files changed, 140 insertions, 989 deletions
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index c8606eec6..3618ab5a1 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -217,6 +217,8 @@ public class D8Command extends BaseCommand {
internal.skipMinification = true;
assert internal.useTreeShaking;
internal.useTreeShaking = false;
+ assert internal.interfaceMethodDesugaring == OffOrAuto.Off;
+ assert internal.tryWithResourcesDesugaring == OffOrAuto.Off;
assert internal.inlineAccessors;
internal.inlineAccessors = false;
assert internal.removeSwitchMaps;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
index c40e2d590..b7036f521 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
@@ -15,7 +15,6 @@ import com.android.tools.r8.ir.synthetic.ForwardMethodSourceCode;
import com.android.tools.r8.ir.synthetic.SynthesizedCode;
import com.google.common.collect.Sets;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
@@ -43,7 +42,9 @@ final class ClassProcessor {
}
final void process(DexClass clazz) {
- assert !clazz.isInterface();
+ if (clazz.isInterface()) {
+ throw new CompilationError("Interface in superclass chain.");
+ }
if (!clazz.isProgramClass()) {
// We assume that library classes don't need to be processed, since they
// are provided by a runtime not supporting default interface methods.
@@ -60,15 +61,8 @@ final class ClassProcessor {
// about methods added to superclasses when we decide if we want to add a default
// method to class `clazz`.
DexType superType = clazz.superType;
- // If superClass definition is missing, just skip this part and let real processing of its
- // subclasses report the error if it is required.
- DexClass superClass = superType == null ? null : rewriter.findDefinitionFor(superType);
- if (superClass != null && superType != rewriter.factory.objectType) {
- if (superClass.isInterface()) {
- throw new CompilationError("Interface `" + superClass.toSourceString()
- + "` used as super class of `" + clazz.toSourceString() + "`.");
- }
- process(superClass);
+ if (superType != null && superType != rewriter.factory.objectType) {
+ process(rewriter.findRequiredClass(superType));
}
if (clazz.interfaces.isEmpty()) {
@@ -101,10 +95,7 @@ final class ClassProcessor {
private DexEncodedMethod addForwardingMethod(DexEncodedMethod defaultMethod, DexClass clazz) {
DexMethod method = defaultMethod.method;
- // NOTE: Never add a forwarding method to methods of classes unknown or coming from android.jar
- // even if this results in invalid code, these classes are never desugared.
- assert rewriter.findDefinitionFor(method.holder) != null
- && !rewriter.findDefinitionFor(method.holder).isLibraryClass();
+ assert !rewriter.findRequiredClass(method.holder).isLibraryClass();
// New method will have the same name, proto, and also all the flags of the
// default method, including bridge flag.
DexMethod newMethod = rewriter.factory.createMethod(clazz.type, method.proto, method.name);
@@ -122,59 +113,23 @@ final class ClassProcessor {
// in this class.
private List<DexEncodedMethod> collectMethodsToImplement(DexClass clazz) {
DefaultMethodsHelper helper = new DefaultMethodsHelper();
- DexClass current = clazz;
+
// Collect candidate default methods by inspecting interfaces implemented
// by this class as well as its superclasses.
- //
- // We assume here that interfaces implemented by java.lang.Object don't
- // have default methods to desugar since they are library interfaces. And we assume object
- // methods don't hide any default interface methods. Default interface method matching Object's
- // methods is supposed to fail with a compilation error.
- // Note that this last assumption will be broken if Object API is augmented with a new method in
- // the future.
- while (current.type != rewriter.factory.objectType) {
+ DexClass current = clazz;
+ while (true) {
for (DexType type : current.interfaces.values) {
- helper.merge(getOrCreateInterfaceInfo(clazz, current, type));
- }
-
- List<DexEncodedMethod> defaultMethodsInDirectInterface = helper.createFullList();
- List<DexEncodedMethod> toBeImplementedFromDirectInterface =
- new ArrayList<>(defaultMethodsInDirectInterface.size());
- hideCandidates(clazz.virtualMethods(),
- defaultMethodsInDirectInterface,
- toBeImplementedFromDirectInterface);
- // toBeImplementedFromDirectInterface are those that we know for sure we need to implement by
- // looking at the already desugared super classes.
- // Remaining methods in defaultMethodsInDirectInterface are those methods we need to look at
- // the hierarchy to know how they should be handled.
- if (toBeImplementedFromDirectInterface.isEmpty()
- && defaultMethodsInDirectInterface.isEmpty()) {
- // No interface with default in direct hierarchy, nothing to do: super already has all that
- // is needed.
- return Collections.emptyList();
+ helper.merge(getOrCreateInterfaceInfo(type));
}
- if (current.superType == null) {
+ DexType superType = current.superType;
+ if (superType == null || superType == rewriter.factory.objectType) {
+ // We assume here that interfaces implemented by java.lang.Object don't
+ // have default methods and don't hide any default interface methods since
+ // they must be library interfaces.
break;
- } else {
- DexClass superClass = rewriter.findDefinitionFor(current.superType);
- if (superClass != null) {
- current = superClass;
- } else {
- String message = "Default method desugaring of `" + clazz.toSourceString() + "` failed";
- if (current == clazz) {
- message += " because its super class `" + clazz.superType.toSourceString()
- + "` is missing";
- } else {
- message +=
- " because it's hierarchy is incomplete. The class `"
- + current.superType.toSourceString()
- + "` is missing and it is the declared super class of `"
- + current.toSourceString() + "`";
- }
- throw new CompilationError(message);
- }
}
+ current = rewriter.findRequiredClass(superType);
}
List<DexEncodedMethod> candidates = helper.createCandidatesList();
@@ -193,31 +148,15 @@ final class ClassProcessor {
}
DexType superType = current.superType;
- DexClass superClass = null;
- if (superType != null) {
- superClass = rewriter.findDefinitionFor(superType);
- // It's available or we would have failed while analyzing the hierarchy for interfaces.
- assert superClass != null;
- }
- if (superClass == null || superType == rewriter.factory.objectType) {
+ if (superType == null || superType == rewriter.factory.objectType) {
// Note that default interface methods must never have same
// name/signature as any method in java.lang.Object (JLS ยง9.4.1.2).
// Everything still in candidate list is not hidden.
toBeImplemented.addAll(candidates);
- // NOTE: we also intentionally remove all candidates coming from android.jar
- // since it is only possible in case v24+ version of android.jar is provided.
- // WARNING: This may result in incorrect code on older platforms!
- toBeImplemented.removeIf(
- method -> {
- DexClass holder = rewriter.findDefinitionFor(method.method.holder);
- // Holder of a found method to implement is a defined interface.
- assert holder != null;
- return holder.isLibraryClass();
- });
return toBeImplemented;
}
- current = superClass;
+ current = rewriter.findRequiredClass(superType);
}
}
@@ -249,56 +188,42 @@ final class ClassProcessor {
}
}
- private DefaultMethodsHelper.Collection getOrCreateInterfaceInfo(
- DexClass classToDesugar,
- DexClass implementing,
- DexType iface) {
+ private DefaultMethodsHelper.Collection getOrCreateInterfaceInfo(DexType iface) {
DefaultMethodsHelper.Collection collection = cache.get(iface);
if (collection != null) {
return collection;
}
- collection = createInterfaceInfo(classToDesugar, implementing, iface);
+ collection = createInterfaceInfo(iface);
cache.put(iface, collection);
return collection;
}
- private DefaultMethodsHelper.Collection createInterfaceInfo(
- DexClass classToDesugar,
- DexClass implementing,
- DexType iface) {
+ private DefaultMethodsHelper.Collection createInterfaceInfo(DexType iface) {
DefaultMethodsHelper helper = new DefaultMethodsHelper();
- DexClass definedInterface = rewriter.findDefinitionFor(iface);
- if (definedInterface == null) {
- String message = "Interface `" + iface.toSourceString()
- + "` not found. It's needed to make sure desugaring of `"
- + classToDesugar.toSourceString() + "` is correct. Desugaring will assume that this"
- + " interface has no default method";
- if (classToDesugar != implementing) {
- message += ". This missing interface is declared in the direct hierarchy of `"
- + implementing.toString() + "`";
- }
- rewriter.warnMissingClass(iface, message);
- return helper.wrapInCollection();
- }
-
- if (!definedInterface.isInterface()) {
+ DexClass clazz = rewriter.findRequiredClass(iface);
+ if (!clazz.isInterface()) {
throw new CompilationError(
- "Type " + iface.toSourceString() + " is referenced as an interface of `"
- + implementing.toString() + "`.");
+ "Type " + iface.toSourceString() + " is expected to be an interface.");
+ }
+ if (clazz.isLibraryClass()) {
+ // For library interfaces we always assume there are no default
+ // methods, since the interface is part of framework provided by
+ // runtime which does not support default interface methods.
+ return DefaultMethodsHelper.Collection.EMPTY;
}
// Merge information from all superinterfaces.
- for (DexType superinterface : definedInterface.interfaces.values) {
- helper.merge(getOrCreateInterfaceInfo(classToDesugar, definedInterface, superinterface));
+ for (DexType superinterface : clazz.interfaces.values) {
+ helper.merge(getOrCreateInterfaceInfo(superinterface));
}
// Hide by virtual methods of this interface.
- for (DexEncodedMethod virtual : definedInterface.virtualMethods()) {
+ for (DexEncodedMethod virtual : clazz.virtualMethods()) {
helper.hideMatches(virtual.method);
}
// Add all default methods of this interface.
- for (DexEncodedMethod encoded : definedInterface.virtualMethods()) {
+ for (DexEncodedMethod encoded : clazz.virtualMethods()) {
if (rewriter.isDefaultMethod(encoded)) {
helper.addDefaultMethod(encoded);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DefaultMethodsHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/DefaultMethodsHelper.java
index ae9a2ae9f..2f25b1972 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DefaultMethodsHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DefaultMethodsHelper.java
@@ -6,10 +6,8 @@ package com.android.tools.r8.ir.desugar;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
@@ -104,18 +102,6 @@ final class DefaultMethodsHelper {
return candidates;
}
- final List<DexEncodedMethod> createFullList() {
- if (candidates.isEmpty() && hidden.isEmpty()) {
- return Collections.emptyList();
- }
-
- List<DexEncodedMethod> fullList =
- new ArrayList<DexEncodedMethod>(candidates.size() + hidden.size());
- fullList.addAll(candidates);
- fullList.addAll(hidden);
- return fullList;
- }
-
// Create default interface collection based on collected information.
final Collection wrapInCollection() {
candidates.removeAll(hidden);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index 5c8faee77..c3f2d087f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -11,7 +11,6 @@ import com.android.tools.r8.graph.DexApplication.Builder;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexItem;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
@@ -25,7 +24,6 @@ import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.InvokeStatic;
import com.android.tools.r8.ir.code.InvokeSuper;
import com.android.tools.r8.ir.conversion.IRConverter;
-import com.android.tools.r8.logging.Log;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.ListIterator;
@@ -69,11 +67,6 @@ public final class InterfaceMethodRewriter {
// to this collection since it is only filled in ClassProcessor running synchronously.
private final Set<DexEncodedMethod> forwardingMethods = Sets.newIdentityHashSet();
- /**
- * A set of dexitems we have reported missing to dedupe warnings.
- */
- private Set<DexItem> reportedMissing = Sets.newIdentityHashSet();
-
/** Defines a minor variation in desugaring. */
public enum Flavor {
/** Process all application resources. */
@@ -106,11 +99,10 @@ public final class InterfaceMethodRewriter {
// Check that static interface methods are not referenced
// from invoke-custom instructions via method handles.
DexCallSite callSite = instruction.asInvokeCustom().getCallSite();
- reportStaticInterfaceMethodHandle(encodedMethod.method, callSite.bootstrapMethod);
+ reportStaticInterfaceMethodHandle(callSite.bootstrapMethod);
for (DexValue arg : callSite.bootstrapArgs) {
if (arg instanceof DexValue.DexValueMethodHandle) {
- reportStaticInterfaceMethodHandle(encodedMethod.method,
- ((DexValue.DexValueMethodHandle) arg).value);
+ reportStaticInterfaceMethodHandle(((DexValue.DexValueMethodHandle) arg).value);
}
}
continue;
@@ -119,17 +111,7 @@ public final class InterfaceMethodRewriter {
if (instruction.isInvokeStatic()) {
InvokeStatic invokeStatic = instruction.asInvokeStatic();
DexMethod method = invokeStatic.getInvokedMethod();
- DexClass clazz = findDefinitionFor(method.holder);
- if (clazz == null) {
- // NOTE: leave unchanged those calls to undefined targets. This may lead to runtime
- // exception but we can not report it as error since it can also be the intended
- // behavior.
- warnMissingClass(encodedMethod.method, method.holder);
- } else if (clazz.isInterface() && !clazz.isLibraryClass()) {
- // NOTE: we intentionally don't desugar static calls into static interface
- // methods coming from android.jar since it is only possible in case v24+
- // version of android.jar is provided.
- // WARNING: This may result in incorrect code on older platforms!
+ if (isInterfaceClass(method.holder)) {
// Retarget call to an appropriate method of companion class.
instructions.replaceCurrentInstruction(
new InvokeStatic(staticAsMethodOfCompanionClass(method),
@@ -141,17 +123,7 @@ public final class InterfaceMethodRewriter {
if (instruction.isInvokeSuper()) {
InvokeSuper invokeSuper = instruction.asInvokeSuper();
DexMethod method = invokeSuper.getInvokedMethod();
- DexClass clazz = findDefinitionFor(method.holder);
- if (clazz == null) {
- // NOTE: leave unchanged those calls to undefined targets. This may lead to runtime
- // exception but we can not report it as error since it can also be the intended
- // behavior.
- warnMissingClass(encodedMethod.method, method.holder);
- } else if (clazz != null && (clazz.isInterface() && !clazz.isLibraryClass())) {
- // NOTE: we intentionally don't desugar super calls into interface methods
- // coming from android.jar since it is only possible in case v24+ version
- // of android.jar is provided.
- // WARNING: This may result in incorrect code on older platforms!
+ if (isInterfaceClass(method.holder)) {
// Retarget call to an appropriate method of companion class.
instructions.replaceCurrentInstruction(
new InvokeStatic(defaultAsMethodOfCompanionClass(method),
@@ -162,27 +134,25 @@ public final class InterfaceMethodRewriter {
}
}
- private void reportStaticInterfaceMethodHandle(DexMethod referencedFrom, DexMethodHandle handle) {
- if (handle.type.isInvokeStatic()) {
- DexClass holderClass = findDefinitionFor(handle.asMethod().holder);
- // NOTE: If the class definition is missing we can't check. Let it be handled as any other
- // missing call target.
- if (holderClass == null) {
- warnMissingClass(referencedFrom, handle.asMethod().holder);
- } else if (holderClass.isInterface()) {
- throw new Unimplemented(
- "Desugaring of static interface method handle as in `"
- + referencedFrom.toSourceString() + "` in is not yet supported.");
- }
+ private void reportStaticInterfaceMethodHandle(DexMethodHandle handle) {
+ if (handle.type.isInvokeStatic() && isInterfaceClass(handle.asMethod().holder)) {
+ throw new Unimplemented(
+ "Desugaring of static interface method handle in is not yet supported.");
}
}
- /**
- * Returns the class definition for the specified type.
- * @return may return null if no definition for the given type is available.
- */
- final DexClass findDefinitionFor(DexType type) {
- return converter.appInfo.definitionFor(type);
+ private boolean isInterfaceClass(DexType type) {
+ return findRequiredClass(type).isInterface();
+ }
+
+ // Returns the class for the type specified, report errors for missing classes.
+ final DexClass findRequiredClass(DexType type) {
+ DexClass clazz = converter.appInfo.definitionFor(type);
+ if (clazz != null) {
+ return clazz;
+ }
+ throw new CompilationError("Type '" + type.toSourceString() +
+ "' required for default and static interface methods desugaring not found.");
}
// Gets the companion class for the interface `type`.
@@ -291,18 +261,4 @@ public final class InterfaceMethodRewriter {
}
return true;
}
-
- void warnMissingClass(DexType missing, String message) {
- // TODO replace by a proper warning mechanic (see b/65154707).
- // TODO think about using a common deduplicating mechanic with Enqueuer
- if (reportedMissing.add(missing)) {
- System.err.println(message);
- }
- }
-
- private void warnMissingClass(DexItem referencedFrom, DexType clazz) {
- warnMissingClass(clazz,
- "Type `" + clazz.toSourceString() + "` was not found, it is required for default or"
- + " static interface methods desugaring of `" + referencedFrom.toSourceString() + "`");
- }
}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 1b9272ce4..b03721fa5 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -83,9 +83,9 @@ public class InternalOptions {
public List<String> logArgumentsFilter = ImmutableList.of();
// Defines interface method rewriter behavior.
- public OffOrAuto interfaceMethodDesugaring = OffOrAuto.Auto;
+ public OffOrAuto interfaceMethodDesugaring = OffOrAuto.Off;
// Defines try-with-resources rewriter behavior.
- public OffOrAuto tryWithResourcesDesugaring = OffOrAuto.Auto;
+ public OffOrAuto tryWithResourcesDesugaring = OffOrAuto.Off;
// Application writing mode.
public OutputMode outputMode = OutputMode.Indexed;
diff --git a/src/test/examplesAndroidO/desugaringwithandroidjar25/DefaultMethodInAndroidJar25.java b/src/test/examplesAndroidO/desugaringwithandroidjar25/DefaultMethodInAndroidJar25.java
deleted file mode 100644
index bec4e6731..000000000
--- a/src/test/examplesAndroidO/desugaringwithandroidjar25/DefaultMethodInAndroidJar25.java
+++ /dev/null
@@ -1,100 +0,0 @@
-// 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 desugaringwithandroidjar25;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.function.Predicate;
-
-public class DefaultMethodInAndroidJar25 {
- public static void main(String[] args) throws Exception {
- ClassWithDefaultPlatformMethods.test();
- }
-}
-
-class ClassWithDefaultPlatformMethods implements Collection<String> {
- private final ArrayList<String> list =
- new ArrayList<String>() {{
- add("First");
- add("Second");
- }};
-
- static void test() {
- ClassWithDefaultPlatformMethods instance = new ClassWithDefaultPlatformMethods();
- instance.forEach(x -> System.out.println("BEFORE: " + x));
- instance.removeIf(x -> true);
- instance.forEach(x -> System.out.println("AFTER: " + x));
- }
-
- @Override
- public int size() {
- throw new AssertionError();
- }
-
- @Override
- public boolean isEmpty() {
- throw new AssertionError();
- }
-
- @Override
- public boolean contains(Object o) {
- throw new AssertionError();
- }
-
- @Override
- public Iterator<String> iterator() {
- return list.iterator();
- }
-
- @Override
- public Object[] toArray() {
- throw new AssertionError();
- }
-
- @Override
- public <T> T[] toArray(T[] a) {
- throw new AssertionError();
- }
-
- @Override
- public boolean add(String s) {
- throw new AssertionError();
- }
-
- @Override
- public boolean remove(Object o) {
- return list.remove(o);
- }
-
- @Override
- public boolean containsAll(Collection<?> c) {
- throw new AssertionError();
- }
-
- @Override
- public boolean addAll(Collection<? extends String> c) {
- throw new AssertionError();
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- throw new AssertionError();
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- throw new AssertionError();
- }
-
- @Override
- public void clear() {
- throw new AssertionError();
- }
-
- @Override
- public boolean removeIf(Predicate<? super String> filter) {
- return Collection.super.removeIf(filter);
- }
-}
diff --git a/src/test/examplesAndroidO/desugaringwithandroidjar25/StaticMethodInAndroidJar25.java b/src/test/examplesAndroidO/desugaringwithandroidjar25/StaticMethodInAndroidJar25.java
deleted file mode 100644
index f07ea8faf..000000000
--- a/src/test/examplesAndroidO/desugaringwithandroidjar25/StaticMethodInAndroidJar25.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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 desugaringwithandroidjar25;
-
-import java.util.Comparator;
-
-public class StaticMethodInAndroidJar25 {
- public static void main(String[] args) throws Exception {
- Comparator<String> comparing =
- Comparator.comparing(x -> x, String::compareTo);
- System.out.println("'a' <> 'b' = " + comparing.compare("a", "b"));
- System.out.println("'b' <> 'b' = " + comparing.compare("b", "b"));
- System.out.println("'c' <> 'b' = " + comparing.compare("c", "b"));
- }
-}
diff --git a/src/test/examplesAndroidO/desugaringwithmissingclasslib1/A.java b/src/test/examplesAndroidO/desugaringwithmissingclasslib1/A.java
deleted file mode 100644
index 98504bd45..000000000
--- a/src/test/examplesAndroidO/desugaringwithmissingclasslib1/A.java
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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 desugaringwithmissingclasslib1;
-
-public interface A {
- default String foo() {
- return "A";
- }
-}
diff --git a/src/test/examplesAndroidO/desugaringwithmissingclasslib2/B.java b/src/test/examplesAndroidO/desugaringwithmissingclasslib2/B.java
deleted file mode 100644
index 1ab424e77..000000000
--- a/src/test/examplesAndroidO/desugaringwithmissingclasslib2/B.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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 desugaringwithmissingclasslib2;
-
-import desugaringwithmissingclasslib1.A;
-
-public interface B extends A {
- @Override
- default String foo() {
- return "B";
- }
-}
diff --git a/src/test/examplesAndroidO/desugaringwithmissingclasslib3/C.java b/src/test/examplesAndroidO/desugaringwithmissingclasslib3/C.java
deleted file mode 100644
index 029f9f4cd..000000000
--- a/src/test/examplesAndroidO/desugaringwithmissingclasslib3/C.java
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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 desugaringwithmissingclasslib3;
-
-import desugaringwithmissingclasslib1.A;
-
-public class C implements A {
-}
diff --git a/src/test/examplesAndroidO/desugaringwithmissingclasstest1/ImplementMethodsWithDefault.java b/src/test/examplesAndroidO/desugaringwithmissingclasstest1/ImplementMethodsWithDefault.java
deleted file mode 100644
index 5f3c1c2a0..000000000
--- a/src/test/examplesAndroidO/desugaringwithmissingclasstest1/ImplementMethodsWithDefault.java
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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 desugaringwithmissingclasstest1;
-
-import desugaringwithmissingclasslib1.A;
-import desugaringwithmissingclasslib2.B;
-
-public class ImplementMethodsWithDefault implements A, B {
-}
diff --git a/src/test/examplesAndroidO/desugaringwithmissingclasstest1/Main.java b/src/test/examplesAndroidO/desugaringwithmissingclasstest1/Main.java
deleted file mode 100644
index 411a0162e..000000000
--- a/src/test/examplesAndroidO/desugaringwithmissingclasstest1/Main.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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 desugaringwithmissingclasstest1;
-
-public class Main {
- public static void main(String[] args) throws Exception {
- ImplementMethodsWithDefault instance = new ImplementMethodsWithDefault();
- try {
- String foo = instance.foo();
- if (foo.equals("B")) {
- System.out.println("OK");
- } else {
- System.out.println("NOT OK: " + foo);
- }
- } catch (Throwable t) {
- System.out.println("NOT OK " + t.getClass() + " " + t.getMessage());
- t.printStackTrace();
- }
- }
-}
diff --git a/src/test/examplesAndroidO/desugaringwithmissingclasstest2/ImplementMethodsWithDefault.java b/src/test/examplesAndroidO/desugaringwithmissingclasstest2/ImplementMethodsWithDefault.java
deleted file mode 100644
index f2ef1b623..000000000
--- a/src/test/examplesAndroidO/desugaringwithmissingclasstest2/ImplementMethodsWithDefault.java
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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 desugaringwithmissingclasstest2;
-
-import desugaringwithmissingclasslib2.B;
-import desugaringwithmissingclasslib3.C;
-
-public class ImplementMethodsWithDefault extends C implements B {
-}
diff --git a/src/test/examplesAndroidO/desugaringwithmissingclasstest2/Main.java b/src/test/examplesAndroidO/desugaringwithmissingclasstest2/Main.java
deleted file mode 100644
index c42ac8127..000000000
--- a/src/test/examplesAndroidO/desugaringwithmissingclasstest2/Main.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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 desugaringwithmissingclasstest2;
-
-public class Main {
- public static void main(String[] args) throws Exception {
- ImplementMethodsWithDefault instance = new ImplementMethodsWithDefault();
- try {
- String foo = instance.foo();
- if (foo.equals("B")) {
- System.out.println("OK");
- } else {
- System.out.println("NOT OK: " + foo);
- }
- } catch (Throwable t) {
- System.out.println("NOT OK " + t.getClass() + " " + t.getMessage());
- t.printStackTrace();
- }
- }
-}
diff --git a/src/test/examplesAndroidO/desugaringwithmissingclasstest3/ImplementMethodsWithDefault.java b/src/test/examplesAndroidO/desugaringwithmissingclasstest3/ImplementMethodsWithDefault.java
deleted file mode 100644
index 482623705..000000000
--- a/src/test/examplesAndroidO/desugaringwithmissingclasstest3/ImplementMethodsWithDefault.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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 desugaringwithmissingclasstest3;
-
-import desugaringwithmissingclasslib2.B;
-import desugaringwithmissingclasslib3.C;
-
-public class ImplementMethodsWithDefault extends C implements B {
- @Override
- public String foo() {
- return "ImplementMethodsWithDefault";
- }
-
- public String getB() {
- return B.super.foo();
- }
-}
diff --git a/src/test/examplesAndroidO/desugaringwithmissingclasstest3/Main.java b/src/test/examplesAndroidO/desugaringwithmissingclasstest3/Main.java
deleted file mode 100644
index bde4d09e9..000000000
--- a/src/test/examplesAndroidO/desugaringwithmissingclasstest3/Main.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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 desugaringwithmissingclasstest3;
-
-public class Main {
- public static void main(String[] args) throws Exception {
- ImplementMethodsWithDefault instance = new ImplementMethodsWithDefault();
- try {
- String b = instance.getB();
- if (b.equals("B")) {
- System.out.println("OK");
- } else {
- System.out.println("NOT OK: " + b);
- }
- } catch (Throwable t) {
- System.out.println("NOT OK " + t.getClass() + " " + t.getMessage());
- t.printStackTrace();
- }
- try {
- String foo = instance.foo();
- if (foo.equals("ImplementMethodsWithDefault")) {
- System.out.println("OK");
- } else {
- System.out.println("NOT OK: " + foo);
- }
- } catch (Throwable t) {
- System.out.println("NOT OK " + t.getClass() + " " + t.getMessage());
- t.printStackTrace();
- }
- }
-}
diff --git a/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
index 2159d6b83..803d76022 100644
--- a/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
@@ -38,14 +38,14 @@ import org.junit.Test;
public abstract class D8IncrementalRunExamplesAndroidOTest
extends RunExamplesAndroidOTest<D8Command.Builder> {
- abstract class D8IncrementalTestRunner extends TestRunner<D8IncrementalTestRunner> {
+ abstract class D8IncrementalTestRunner extends TestRunner {
D8IncrementalTestRunner(String testName, String packageName, String mainClass) {
super(testName, packageName, mainClass);
}
@Override
- D8IncrementalTestRunner withMinApiLevel(int minApiLevel) {
+ TestRunner withMinApiLevel(int minApiLevel) {
return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel));
}
@@ -154,11 +154,12 @@ public abstract class D8IncrementalRunExamplesAndroidOTest
builder = transformation.apply(builder);
}
builder = builder.setOutputMode(outputMode);
+ builder = builder.addLibraryFiles(
+ Paths.get(ToolHelper.getAndroidJar(builder.getMinApiLevel())));
if (output != null) {
builder = builder.setOutputPath(output);
}
- addLibraryReference(builder, Paths.get(ToolHelper.getAndroidJar(
- androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion)));
+ addLibraryReference(builder, Paths.get(ToolHelper.getAndroidJar(builder.getMinApiLevel())));
D8Command command = builder.build();
try {
return ToolHelper.runD8(command, this::combinedOptionConsumer);
@@ -287,7 +288,6 @@ public abstract class D8IncrementalRunExamplesAndroidOTest
Assert.assertArrayEquals(expectedFileNames, dexFiles);
}
- @Override
abstract D8IncrementalTestRunner test(String testName, String packageName, String mainClass);
static byte[] readFromResource(Resource resource) throws IOException {
diff --git a/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
index c2ac969a7..d7076148d 100644
--- a/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
@@ -52,11 +52,6 @@ public class D8LazyRunExamplesAndroidOTest
builder.addLibraryResourceProvider(
PreloadedClassFileProvider.fromArchive(location));
}
-
- @Override
- D8LazyTestRunner self() {
- return this;
- }
}
@Override
diff --git a/src/test/java/com/android/tools/r8/D8NonLazyRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8NonLazyRunExamplesAndroidOTest.java
index 99fe81cfe..5b2977c47 100644
--- a/src/test/java/com/android/tools/r8/D8NonLazyRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8NonLazyRunExamplesAndroidOTest.java
@@ -23,13 +23,7 @@ public class D8NonLazyRunExamplesAndroidOTest
@Override
void addLibraryReference(D8Command.Builder builder, Path location) throws IOException {
- builder.addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(
- androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion)));
- }
-
- @Override
- D8LazyTestRunner self() {
- return this;
+ builder.addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(builder.getMinApiLevel())));
}
}
diff --git a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
index b2adb201a..6f516242d 100644
--- a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
@@ -4,58 +4,33 @@
package com.android.tools.r8;
-import static com.android.tools.r8.dex.Constants.ANDROID_K_API;
-import static com.android.tools.r8.dex.Constants.ANDROID_O_API;
-
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.OffOrAuto;
-import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.UnaryOperator;
-import org.hamcrest.core.CombinableMatcher;
-import org.hamcrest.core.IsInstanceOf;
-import org.hamcrest.core.StringContains;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.internal.matchers.ThrowableMessageMatcher;
public class D8RunExamplesAndroidOTest extends RunExamplesAndroidOTest<D8Command.Builder> {
- class D8TestRunner extends TestRunner<D8TestRunner> {
+ class D8TestRunner extends TestRunner {
D8TestRunner(String testName, String packageName, String mainClass) {
super(testName, packageName, mainClass);
}
@Override
- D8TestRunner withMinApiLevel(int minApiLevel) {
+ TestRunner withMinApiLevel(int minApiLevel) {
return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel));
}
- D8TestRunner withClasspath(Path... classpath) {
- return withBuilderTransformation(b -> {
- try {
- return b.addClasspathFiles(classpath);
- } catch (IOException e) {
- throw new AssertionError(e);
- }
- });
- }
-
-
@Override
void build(Path inputFile, Path out) throws Throwable {
D8Command.Builder builder = D8Command.builder();
for (UnaryOperator<D8Command.Builder> transformation : builderTransformations) {
builder = transformation.apply(builder);
}
- builder.addLibraryFiles(
- Paths.get(
- ToolHelper.getAndroidJar(
- androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion)));
+ builder.addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(builder.getMinApiLevel())));
D8Command command = builder.addProgramFiles(inputFile).setOutputPath(out).build();
try {
ToolHelper.runD8(command, this::combinedOptionConsumer);
@@ -65,361 +40,10 @@ public class D8RunExamplesAndroidOTest extends RunExamplesAndroidOTest<D8Command
throw re.getCause() == null ? re : re.getCause();
}
}
-
- @Override
- D8TestRunner self() {
- return this;
- }
- }
-
- @Test
- public void testDefaultInInterfaceWithoutDesugaring() throws Throwable {
- // lib1: interface A { default String foo() { return "A"; } }
- D8TestRunner lib1 =
- test("testDefaultInInterfaceWithoutDesugaring", "desugaringwithmissingclasslib1", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Off)
- .withMinApiLevel(ANDROID_K_API);
- try {
- lib1.build();
-
- // compilation should have failed on CompilationError since A is declaring a default method.
- Assert.fail();
- } catch (CompilationError | CompilationException e) {
- // Expected.
- }
- }
-
- @Test
- public void testMissingInterfaceDesugared() throws Throwable {
- // lib1: interface A { default String foo() { return "A"; } }
- D8TestRunner lib1 =
- test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withMinApiLevel(ANDROID_K_API);
- lib1.build();
-
- // lib2: interface B extends A { default String foo() { return "B"; } }
- // lib2 is compiled with full classpath
- D8TestRunner lib2 =
- test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(ANDROID_K_API);
- lib2.build();
-
- // test: class ImplementMethodsWithDefault implements A, B {} should get its foo implementation
- // from B.
- // test is compiled with incomplete classpath: lib2 is missing so ImplementMethodsWithDefault is
- // missing one of it interfaces.
- D8TestRunner test =
- test("desugaringwithmissingclasstest1", "desugaringwithmissingclasstest1", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(ANDROID_K_API);
- test.build();
-
- // TODO check compilation warnings are correctly reported
- // B is missing so compiled code makes no sense, no need to test execution.
- }
-
- @Test
- public void testMissingInterfaceDesugared2AndroidK() throws Throwable {
- int minApi = ANDROID_K_API;
-
- // lib1: interface A { default String foo() { return "A"; } }
- D8TestRunner lib1 =
- test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withMinApiLevel(minApi);
- Path lib1Dex = lib1.build();
-
- // lib2: interface B extends A { default String foo() { return "B"; } }
- // lib2 is compiled with full classpath
- D8TestRunner lib2 =
- test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path lib2Dex = lib2.build();
-
- // lib3: class C implements A {}
- // lib3 is compiled with full classpath
- D8TestRunner lib3 =
- test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path lib3Dex = lib3.build();
-
- // test: class ImplementMethodsWithDefault extends C implements B should get its foo
- // implementation from B.
- // test is compiled with incomplete classpath: lib2 and lib3 are missing so
- // ImplementMethodsWithDefault is missing all its hierarchy.
- D8TestRunner test =
- test("desugaringwithmissingclasstest2", "desugaringwithmissingclasstest2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path testDex = test.build();
- // TODO check compilation warnings are correctly reported
-
- // Missing interface B is causing the wrong code to be executed.
- thrown.expect(AssertionError.class);
- execute(
- "testMissingInterfaceDesugared2AndroidK",
- "desugaringwithmissingclasstest2.Main",
- new Path[] {
- lib1.getInputJar(), lib2.getInputJar(), lib3.getInputJar(), test.getInputJar()
- },
- new Path[] {lib1Dex, lib2Dex, lib3Dex, testDex});
- }
-
- @Test
- public void testMissingInterfaceDesugared2AndroidO() throws Throwable {
- int minApi = ANDROID_O_API;
- // lib1: interface A { default String foo() { return "A"; } }
- D8TestRunner lib1 =
- test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withMinApiLevel(minApi);
- Path lib1Dex = lib1.build();
-
- // lib2: interface B extends A { default String foo() { return "B"; } }
- // lib2 is compiled with full classpath
- D8TestRunner lib2 =
- test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path lib2Dex = lib2.build();
-
- // lib3: class C implements A {}
- // lib3 is compiled with full classpath
- D8TestRunner lib3 =
- test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path lib3Dex = lib3.build();
-
- // test: class ImplementMethodsWithDefault extends C implements B should get its foo
- // implementation from B.
- // test is compiled with incomplete classpath: lib2 and lib3 are missing so
- // ImplementMethodsWithDefault is missing all its hierarchy.
- D8TestRunner test =
- test("desugaringwithmissingclasstest2", "desugaringwithmissingclasstest2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path testDex = test.build();
- execute(
- "testMissingInterfaceDesugared2AndroidO",
- "desugaringwithmissingclasstest2.Main",
- new Path[] {
- lib1.getInputJar(), lib2.getInputJar(), lib3.getInputJar(), test.getInputJar()
- },
- new Path[] {lib1Dex, lib2Dex, lib3Dex, testDex});
- }
-
- @Test
- public void testCallToMissingSuperInterfaceDesugaredAndroidK() throws Throwable {
-
- int minApi = ANDROID_K_API;
- // lib1: interface A { default String foo() { return "A"; } }
- D8TestRunner lib1 =
- test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withMinApiLevel(minApi);
- Path lib1Dex = lib1.build();
-
- // lib2: interface B extends A { default String foo() { return "B"; } }
- // lib2 is compiled with full classpath
- D8TestRunner lib2 =
- test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path lib2Dex = lib2.build();
-
- // lib3: class C implements A {}
- // lib3 is compiled with full classpath
- D8TestRunner lib3 =
- test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path lib3Dex = lib3.build();
-
- // test: class ImplementMethodsWithDefault extends C implements B
- // { String getB() { return B.super.foo(); }
- // Should be able to call implementation from B.
- // test is compiled with incomplete classpath: lib2, i.e. B definition, is missing.
- D8TestRunner test =
- test("desugaringwithmissingclasstest3", "desugaringwithmissingclasstest3", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar(), lib3.getInputJar())
- .withMinApiLevel(minApi);
- Path testDex = test.build();
- // TODO check compilation warnings are correctly reported
-
- // Missing interface B is causing the wrong method to be executed.
- thrown.expect(AssertionError.class);
- execute(
- "testCallToMissingSuperInterfaceDesugaredAndroidK",
- "desugaringwithmissingclasstest3.Main",
- new Path[] {
- lib1.getInputJar(), lib2.getInputJar(), lib3.getInputJar(), test.getInputJar()
- },
- new Path[] {lib1Dex, lib2Dex, lib3Dex, testDex});
- }
-
- @Test
- public void testCallToMissingSuperInterfaceDesugaredAndroidO() throws Throwable {
- int minApi = ANDROID_O_API;
- // lib1: interface A { default String foo() { return "A"; } }
- D8TestRunner lib1 =
- test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withMinApiLevel(minApi);
- Path lib1Dex = lib1.build();
-
- // lib2: interface B extends A { default String foo() { return "B"; } }
- // lib2 is compiled with full classpath
- D8TestRunner lib2 =
- test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path lib2Dex = lib2.build();
-
- // lib3: class C implements A {}
- // lib3 is compiled with full classpath
- D8TestRunner lib3 =
- test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path lib3Dex = lib3.build();
-
- // test: class ImplementMethodsWithDefault extends C implements B
- // { String getB() { return B.super.foo(); }
- // Should be able to call implementation from B.
- // test is compiled with incomplete classpath: lib2, i.e. B definition, is missing.
- D8TestRunner test =
- test("desugaringwithmissingclasstest3", "desugaringwithmissingclasstest3", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar(), lib3.getInputJar())
- .withMinApiLevel(minApi);
- Path testDex = test.build();
- execute(
- "testCallToMissingSuperInterfaceDesugaredAndroidO",
- "desugaringwithmissingclasstest3.Main",
- new Path[] {
- lib1.getInputJar(), lib2.getInputJar(), lib3.getInputJar(), test.getInputJar()
- },
- new Path[] {lib1Dex, lib2Dex, lib3Dex, testDex});
- }
-
- @Test
- public void testMissingSuperDesugaredAndroidK() throws Throwable {
- int minApi = ANDROID_K_API;
-
- // lib1: interface A { default String foo() { return "A"; } }
- D8TestRunner lib1 =
- test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withMinApiLevel(minApi);
- lib1.build();
-
- // lib2: interface B extends A { default String foo() { return "B"; } }
- // lib2 is compiled with full classpath
- D8TestRunner lib2 =
- test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- lib2.build();
-
- // lib3: class C implements A {}
- // lib3 is compiled with full classpath
- D8TestRunner lib3 =
- test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- lib3.build();
-
- // test: class ImplementMethodsWithDefault extends C implements B should get its foo
- // implementation from B.
- // test is compiled with incomplete classpath: lib3 is missing so
- // ImplementMethodsWithDefault is missing its super class.
- D8TestRunner test =
- test("desugaringwithmissingclasstest2", "desugaringwithmissingclasstest2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withClasspath(lib2.getInputJar())
- .withMinApiLevel(minApi);
- thrown.expect(
- new CombinableMatcher<CompilationError>(new IsInstanceOf(CompilationError.class))
- .and(new ThrowableMessageMatcher<CompilationError>(
- new StringContains("desugaringwithmissingclasstest2.ImplementMethodsWithDefault")))
- .and(new ThrowableMessageMatcher<CompilationError>(
- new StringContains("desugaringwithmissingclasslib3.C"))));
- test.build();
- }
-
- @Test
- public void testMissingSuperDesugaredAndroidO() throws Throwable {
- int minApi = ANDROID_O_API;
-
- // lib1: interface A { default String foo() { return "A"; } }
- D8TestRunner lib1 =
- test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withMinApiLevel(minApi);
- Path lib1Dex = lib1.build();
-
- // lib2: interface B extends A { default String foo() { return "B"; } }
- // lib2 is compiled with full classpath
- D8TestRunner lib2 =
- test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path lib2Dex = lib2.build();
-
- // lib3: class C implements A {}
- // lib3 is compiled with full classpath
- D8TestRunner lib3 =
- test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withMinApiLevel(minApi);
- Path lib3Dex = lib3.build();
-
- // test: class ImplementMethodsWithDefault extends C implements B should get its foo
- // implementation from B.
- // test is compiled with incomplete classpath: lib3 is missing so
- // ImplementMethodsWithDefault is missing its super class.
- D8TestRunner test =
- test("desugaringwithmissingclasstest2", "desugaringwithmissingclasstest2", "N/A")
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withClasspath(lib1.getInputJar())
- .withClasspath(lib2.getInputJar())
- .withMinApiLevel(minApi);
- Path testDex = test.build();
-
- execute(
- "testMissingSuperDesugaredAndroidO",
- "desugaringwithmissingclasstest2.Main",
- new Path[] {
- lib1.getInputJar(), lib2.getInputJar(), lib3.getInputJar(), test.getInputJar()
- },
- new Path[] {lib1Dex, lib2Dex, lib3Dex, testDex});
}
@Override
- D8TestRunner test(String testName, String packageName, String mainClass) {
+ TestRunner test(String testName, String packageName, String mainClass) {
return new D8TestRunner(testName, packageName, mainClass);
}
}
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index 20b8b9c18..aa3061598 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -136,6 +136,21 @@ public abstract class R8RunArtTestsTest {
.put("975-iface-private", Constants.ANDROID_N_API)
.build();
+ // Tests requiring interface method desugaring because they explicitly or
+ // implicitly define static or default interface methods and are enabled
+ // on pre-N Android.
+ private static List<String> enableInterfaceMethodDesugaring =
+ ImmutableList.of(
+ "563-checker-invoke-super",
+ "604-hot-static-interface",
+ "961-default-iface-resolution-gen",
+ "963-default-range-smali",
+ "965-default-verify",
+ "967-default-ame",
+ "969-iface-super",
+ "978-virtual-interface"
+ );
+
// Tests that timeout when run with Art.
private static final Multimap<String, TestCondition> timeoutOrSkipRunWithArt =
new ImmutableListMultimap.Builder<String, TestCondition>()
@@ -184,9 +199,8 @@ public abstract class R8RunArtTestsTest {
// Tests that are never compiled or run.
private static List<String> skipAltogether = ImmutableList.of(
- // Those tests contains an invalid type hierarchy, which we cannot currently handle.
+ // This test contains an invalid type hierarchy, which we cannot currently handle.
"065-mismatched-implements",
- "066-mismatched-super",
// This test contains invalid dex code that reads uninitialized registers after an
// an instruction that would in any case throw (implicit via aget null 0).
"706-jit-skip-compilation",
@@ -1125,12 +1139,7 @@ public abstract class R8RunArtTestsTest {
Integer minSdkVersion = needMinSdkVersion.get(name);
if (minSdkVersion != null) {
builder.setMinApiLevel(minSdkVersion);
- builder.addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(minSdkVersion)));
- } else {
- builder.addLibraryFiles(Paths.get(
- ToolHelper.getAndroidJar(Constants.DEFAULT_ANDROID_API)));
}
-
D8Output output = D8.run(builder.build());
output.write(Paths.get(resultPath));
break;
@@ -1153,6 +1162,9 @@ public abstract class R8RunArtTestsTest {
ToolHelper.runR8(
builder.build(),
options -> {
+ if (enableInterfaceMethodDesugaring.contains(name)) {
+ options.interfaceMethodDesugaring = OffOrAuto.Auto;
+ }
if (disableInlining) {
options.inlineAccessors = false;
}
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
index e63b1553b..6c45f40a4 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
@@ -46,14 +46,14 @@ public class R8RunExamplesAndroidOTest extends RunExamplesAndroidOTest<R8Command
.run();
}
- class R8TestRunner extends TestRunner<R8TestRunner> {
+ class R8TestRunner extends TestRunner {
R8TestRunner(String testName, String packageName, String mainClass) {
super(testName, packageName, mainClass);
}
@Override
- R8TestRunner withMinApiLevel(int minApiLevel) {
+ TestRunner withMinApiLevel(int minApiLevel) {
return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel));
}
@@ -64,23 +64,16 @@ public class R8RunExamplesAndroidOTest extends RunExamplesAndroidOTest<R8Command
for (UnaryOperator<R8Command.Builder> transformation : builderTransformations) {
builder = transformation.apply(builder);
}
- builder.addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(
- androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion)));
R8Command command = builder.addProgramFiles(inputFile).setOutputPath(out).build();
ToolHelper.runR8(command, this::combinedOptionConsumer);
} catch (ExecutionException e) {
throw e.getCause();
}
}
-
- @Override
- R8TestRunner self() {
- return this;
- }
}
@Override
- R8TestRunner test(String testName, String packageName, String mainClass) {
+ TestRunner test(String testName, String packageName, String mainClass) {
return new R8TestRunner(testName, packageName, mainClass);
}
diff --git a/src/test/java/com/android/tools/r8/RunExamplesAndroidNTest.java b/src/test/java/com/android/tools/r8/RunExamplesAndroidNTest.java
index 9d745f623..7594b0cf2 100644
--- a/src/test/java/com/android/tools/r8/RunExamplesAndroidNTest.java
+++ b/src/test/java/com/android/tools/r8/RunExamplesAndroidNTest.java
@@ -133,8 +133,7 @@ public abstract class RunExamplesAndroidNTest<B> {
thrown.expect(ApiLevelException.class);
test("staticinterfacemethods-error-due-to-min-sdk", "interfacemethods",
"StaticInterfaceMethods")
- .withInterfaceMethodDesugaring(OffOrAuto.Off)
- .run();
+ .run();
}
@Test
@@ -150,7 +149,6 @@ public abstract class RunExamplesAndroidNTest<B> {
thrown.expect(ApiLevelException.class);
test("defaultmethods-error-due-to-min-sdk", "interfacemethods",
"DefaultMethods")
- .withInterfaceMethodDesugaring(OffOrAuto.Off)
.run();
}
diff --git a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
index 012a077a7..937f55c63 100644
--- a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
@@ -22,35 +22,29 @@ import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.OffOrAuto;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
-import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
-public abstract class RunExamplesAndroidOTest
- <B extends BaseCommand.Builder<? extends BaseCommand, B>> {
+public abstract class RunExamplesAndroidOTest<B> {
static final String EXAMPLE_DIR = ToolHelper.EXAMPLES_ANDROID_O_BUILD_DIR;
- abstract class TestRunner<C extends TestRunner<C>> {
+ abstract class TestRunner {
final String testName;
final String packageName;
final String mainClass;
- Integer androidJarVersion = null;
-
final List<Consumer<InternalOptions>> optionConsumers = new ArrayList<>();
final List<Consumer<DexInspector>> dexInspectorChecks = new ArrayList<>();
final List<UnaryOperator<B>> builderTransformations = new ArrayList<>();
@@ -61,22 +55,20 @@ public abstract class RunExamplesAndroidOTest
this.mainClass = mainClass;
}
- abstract C self();
-
- C withDexCheck(Consumer<DexInspector> check) {
+ TestRunner withDexCheck(Consumer<DexInspector> check) {
dexInspectorChecks.add(check);
- return self();
+ return this;
}
- C withClassCheck(Consumer<FoundClassSubject> check) {
+ TestRunner withClassCheck(Consumer<FoundClassSubject> check) {
return withDexCheck(inspector -> inspector.forAllClasses(check));
}
- C withMethodCheck(Consumer<FoundMethodSubject> check) {
+ TestRunner withMethodCheck(Consumer<FoundMethodSubject> check) {
return withClassCheck(clazz -> clazz.forAllMethods(check));
}
- <T extends InstructionSubject> C withInstructionCheck(
+ <T extends InstructionSubject> TestRunner withInstructionCheck(
Predicate<InstructionSubject> filter, Consumer<T> check) {
return withMethodCheck(method -> {
if (method.isAbstract()) {
@@ -89,22 +81,22 @@ public abstract class RunExamplesAndroidOTest
});
}
- C withOptionConsumer(Consumer<InternalOptions> consumer) {
+ TestRunner withOptionConsumer(Consumer<InternalOptions> consumer) {
optionConsumers.add(consumer);
- return self();
+ return this;
}
- C withInterfaceMethodDesugaring(OffOrAuto behavior) {
+ TestRunner withInterfaceMethodDesugaring(OffOrAuto behavior) {
return withOptionConsumer(o -> o.interfaceMethodDesugaring = behavior);
}
- C withTryWithResourcesDesugaring(OffOrAuto behavior) {
+ TestRunner withTryWithResourcesDesugaring(OffOrAuto behavior) {
return withOptionConsumer(o -> o.tryWithResourcesDesugaring = behavior);
}
- C withBuilderTransformation(UnaryOperator<B> builderTransformation) {
+ TestRunner withBuilderTransformation(UnaryOperator<B> builderTransformation) {
builderTransformations.add(builderTransformation);
- return self();
+ return this;
}
void combinedOptionConsumer(InternalOptions options) {
@@ -113,18 +105,6 @@ public abstract class RunExamplesAndroidOTest
}
}
- Path build() throws Throwable {
- Path inputFile = getInputJar();
- Path out = temp.getRoot().toPath().resolve(testName + ZIP_EXTENSION);
-
- build(inputFile, out);
- return out;
- }
-
- Path getInputJar() {
- return Paths.get(EXAMPLE_DIR, packageName + JAR_EXTENSION);
- }
-
void run() throws Throwable {
if (compilationErrorExpected(testName)) {
thrown.expect(CompilationError.class);
@@ -134,7 +114,7 @@ public abstract class RunExamplesAndroidOTest
}
String qualifiedMainClass = packageName + "." + mainClass;
- Path inputFile = getInputJar();
+ Path inputFile = Paths.get(EXAMPLE_DIR, packageName + JAR_EXTENSION);
Path out = temp.getRoot().toPath().resolve(testName + ZIP_EXTENSION);
build(inputFile, out);
@@ -143,6 +123,11 @@ public abstract class RunExamplesAndroidOTest
return;
}
+ boolean expectedToFail = expectedToFail(testName);
+ if (expectedToFail) {
+ thrown.expect(Throwable.class);
+ }
+
if (!dexInspectorChecks.isEmpty()) {
DexInspector inspector = new DexInspector(out);
for (Consumer<DexInspector> check : dexInspectorChecks) {
@@ -150,16 +135,21 @@ public abstract class RunExamplesAndroidOTest
}
}
- execute(testName, qualifiedMainClass, new Path[]{inputFile}, new Path[]{out});
+ String output = ToolHelper.runArtNoVerificationErrors(out.toString(), qualifiedMainClass);
+ if (!expectedToFail) {
+ ToolHelper.ProcessResult javaResult =
+ ToolHelper.runJava(ImmutableList.of(inputFile.toString()), qualifiedMainClass);
+ assertEquals("JVM run failed", javaResult.exitCode, 0);
+ assertTrue(
+ "JVM output does not match art output.\n\tjvm: "
+ + javaResult.stdout
+ + "\n\tart: "
+ + output,
+ output.equals(javaResult.stdout));
+ }
}
- abstract C withMinApiLevel(int minApiLevel);
-
- C withAndroidJar(int androidJarVersion) {
- assert this.androidJarVersion == null;
- this.androidJarVersion = androidJarVersion;
- return self();
- }
+ abstract TestRunner withMinApiLevel(int minApiLevel);
abstract void build(Path inputFile, Path out) throws Throwable;
}
@@ -179,11 +169,7 @@ public abstract class RunExamplesAndroidOTest
// Dex version not supported
"invokepolymorphic",
"invokecustom",
- "invokecustom2",
- "DefaultMethodInAndroidJar25",
- "StaticMethodInAndroidJar25",
- "testMissingInterfaceDesugared2AndroidO",
- "testCallToMissingSuperInterfaceDesugaredAndroidO"
+ "invokecustom2"
),
DexVm.ART_5_1_1, ImmutableList.of(
// API not supported
@@ -192,11 +178,7 @@ public abstract class RunExamplesAndroidOTest
// Dex version not supported
"invokepolymorphic",
"invokecustom",
- "invokecustom2",
- "DefaultMethodInAndroidJar25",
- "StaticMethodInAndroidJar25",
- "testMissingInterfaceDesugared2AndroidO",
- "testCallToMissingSuperInterfaceDesugaredAndroidO"
+ "invokecustom2"
),
DexVm.ART_6_0_1, ImmutableList.of(
// API not supported
@@ -205,11 +187,7 @@ public abstract class RunExamplesAndroidOTest
// Dex version not supported
"invokepolymorphic",
"invokecustom",
- "invokecustom2",
- "DefaultMethodInAndroidJar25",
- "StaticMethodInAndroidJar25",
- "testMissingInterfaceDesugared2AndroidO",
- "testCallToMissingSuperInterfaceDesugaredAndroidO"
+ "invokecustom2"
),
DexVm.ART_7_0_0, ImmutableList.of(
// API not supported
@@ -217,9 +195,7 @@ public abstract class RunExamplesAndroidOTest
// Dex version not supported
"invokepolymorphic",
"invokecustom",
- "invokecustom2",
- "testMissingInterfaceDesugared2AndroidO",
- "testCallToMissingSuperInterfaceDesugaredAndroidO"
+ "invokecustom2"
),
DexVm.ART_DEFAULT, ImmutableList.of(
)
@@ -299,24 +275,6 @@ public abstract class RunExamplesAndroidOTest
}
@Test
- public void desugarDefaultMethodInAndroidJar25() throws Throwable {
- test("DefaultMethodInAndroidJar25", "desugaringwithandroidjar25", "DefaultMethodInAndroidJar25")
- .withMinApiLevel(ANDROID_K_API)
- .withAndroidJar(ANDROID_O_API)
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .run();
- }
-
- @Test
- public void desugarStaticMethodInAndroidJar25() throws Throwable {
- test("StaticMethodInAndroidJar25", "desugaringwithandroidjar25", "StaticMethodInAndroidJar25")
- .withMinApiLevel(ANDROID_K_API)
- .withAndroidJar(ANDROID_O_API)
- .withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .run();
- }
-
- @Test
public void lambdaDesugaringValueAdjustments() throws Throwable {
test("lambdadesugaring-value-adjustments", "lambdadesugaring", "ValueAdjustments")
.withMinApiLevel(ANDROID_K_API)
@@ -366,34 +324,5 @@ public abstract class RunExamplesAndroidOTest
.run();
}
- abstract RunExamplesAndroidOTest<B>.TestRunner<?> test(String testName, String packageName, String mainClass);
-
- void execute(
- String testName,
- String qualifiedMainClass, Path[] jars, Path[] dexes)
- throws IOException {
-
- boolean expectedToFail = expectedToFail(testName);
- if (expectedToFail) {
- thrown.expect(Throwable.class);
- }
- String output = ToolHelper.runArtNoVerificationErrors(
- Arrays.stream(dexes).map(path -> path.toString()).collect(Collectors.toList()),
- qualifiedMainClass,
- null);
- if (!expectedToFail) {
- ToolHelper.ProcessResult javaResult =
- ToolHelper.runJava(
- Arrays.stream(jars).map(path -> path.toString()).collect(Collectors.toList()),
- qualifiedMainClass);
- assertEquals("JVM run failed", javaResult.exitCode, 0);
- assertTrue(
- "JVM output does not match art output.\n\tjvm: "
- + javaResult.stdout
- + "\n\tart: "
- + output,
- output.equals(javaResult.stdout));
- }
- }
-
+ abstract TestRunner test(String testName, String packageName, String mainClass);
}
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 72e9e8138..663d6bd68 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -14,11 +14,15 @@ import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.shaking.ProguardConfigurationParser;
+import com.android.tools.r8.shaking.ProguardConfigurationRule;
import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.shaking.RootSetBuilder;
+import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
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 com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
diff --git a/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java b/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
index 39d90d64d..b6debff76 100644
--- a/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
@@ -45,6 +45,14 @@ public class BasicTestDependenciesDesugaringTest {
}
private static Set<String> knownIssues = Sets.newHashSet(new String[]{
+ "espresso-core-3.0.0.jar",
+ "hamcrest-integration-1.3.jar",
+ "hamcrest-library-1.3.jar",
+ "junit-4.12.jar",
+ "support-core-ui-25.4.0.jar",
+ "support-media-compat-25.4.0.jar",
+ "support-fragment-25.4.0.jar",
+ "support-compat-25.4.0.jar"
});
@Rule
@@ -90,18 +98,4 @@ public class BasicTestDependenciesDesugaringTest {
.build(),
options -> options.interfaceMethodDesugaring = OffOrAuto.Auto);
}
-
- @Test
- public void testCompileDontDesugarDefault() throws IOException, CompilationException {
- if (knownIssues.contains(name)) {
- thrown.expect(CompilationError.class);
- }
- ToolHelper.runD8(
- D8Command.builder().addClasspathFiles(classpath)
- .addProgramFiles(toCompile)
- .addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(Constants.ANDROID_K_API)))
- .setMinApiLevel(Constants.ANDROID_K_API)
- .build(),
- options -> options.interfaceMethodDesugaring = OffOrAuto.Off);
- }
}