Merge "Add tests for valid class files with name conflict."
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
index 8d087b6..8d5857a 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
@@ -182,6 +182,14 @@
}
}
+ public void swapSuccessors(BasicBlock a, BasicBlock b) {
+ assert a != b;
+ int aIndex = successors.indexOf(a);
+ int bIndex = successors.indexOf(b);
+ assert aIndex >= 0 && bIndex >= 0;
+ swapSuccessorsByIndex(aIndex, bIndex);
+ }
+
public void swapSuccessorsByIndex(int index1, int index2) {
assert index1 != index2;
if (hasCatchHandlers()) {
@@ -1053,20 +1061,25 @@
return hare;
}
- public boolean isSimpleAlwaysThrowingPath() {
+ public boolean isSimpleAlwaysThrowingPath(boolean failOnMissingPosition) {
// See Floyd's cycle-finding algorithm for reference.
BasicBlock hare = this;
BasicBlock tortuous = this;
boolean advance = false;
while (true) {
List<BasicBlock> normalSuccessors = hare.getNormalSuccessors();
- if (normalSuccessors.size() == 0) {
- return hare.exit().isThrow();
- }
if (normalSuccessors.size() > 1) {
return false;
}
+ if (failOnMissingPosition && hasThrowingInstructionWithoutPosition(hare)) {
+ return false;
+ }
+
+ if (normalSuccessors.size() == 0) {
+ return hare.exit().isThrow();
+ }
+
hare = normalSuccessors.get(0);
tortuous = advance ? tortuous.getNormalSuccessors().get(0) : tortuous;
advance = !advance;
@@ -1076,6 +1089,15 @@
}
}
+ private boolean hasThrowingInstructionWithoutPosition(BasicBlock hare) {
+ for (Instruction instruction : hare.instructions) {
+ if (instruction.instructionTypeCanThrow() && instruction.getPosition().isNone()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public Position getPosition() {
BasicBlock block = endOfGotoChain();
return block != null ? block.entry().getPosition() : Position.none();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 30dde25..769228d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -1434,7 +1434,7 @@
// and the dominator or the original block has catch handlers.
continue;
}
- if (!dominator.isSimpleAlwaysThrowingPath()) {
+ if (!dominator.isSimpleAlwaysThrowingPath(false)) {
// Only move string constants into blocks being part of simple
// always throwing path.
continue;
@@ -1874,11 +1874,16 @@
public void simplifyIf(IRCode code, TypeEnvironment typeEnvironment) {
int color = code.reserveMarkingColor();
+ boolean ifBranchFlipped = false;
for (BasicBlock block : code.blocks) {
if (block.isMarked(color)) {
continue;
}
if (block.exit().isIf()) {
+ // Flip then/else branches if needed.
+ if (flipIfBranchesIfNeeded(block, code.hasDebugPositions)) {
+ ifBranchFlipped = true;
+ }
// First rewrite zero comparison.
rewriteIfWithConstZero(block);
@@ -1934,6 +1939,9 @@
}
code.removeMarkedBlocks(color);
code.returnMarkingColor(color);
+ if (ifBranchFlipped) {
+ code.traceBlocks();
+ }
assert code.isConsistentSSA();
}
@@ -2199,6 +2207,28 @@
}
}
+ private boolean flipIfBranchesIfNeeded(BasicBlock block, boolean failOnMissingPosition) {
+ If theIf = block.exit().asIf();
+ BasicBlock trueTarget = theIf.getTrueTarget();
+ BasicBlock fallthrough = theIf.fallthroughBlock();
+ assert trueTarget != fallthrough;
+
+ if (!fallthrough.isSimpleAlwaysThrowingPath(failOnMissingPosition) ||
+ trueTarget.isSimpleAlwaysThrowingPath(failOnMissingPosition)) {
+ return false;
+ }
+
+ // In case fall-through block always trows there is a good chance that it
+ // is created for error checks and 'trueTarget' represents most more common
+ // non-error case. Flipping the if in this case may result in faster code
+ // on older Android versions.
+ List<Value> inValues = theIf.inValues();
+ If newIf = new If(theIf.getType().inverted(), inValues);
+ block.replaceLastInstruction(newIf);
+ block.swapSuccessors(trueTarget, fallthrough);
+ return true;
+ }
+
public void rewriteLongCompareAndRequireNonNull(IRCode code, InternalOptions options) {
if (options.canUseLongCompareAndObjectsNonNull()) {
return;
diff --git a/src/test/java/com/android/tools/r8/AsmTestBase.java b/src/test/java/com/android/tools/r8/AsmTestBase.java
index b1b572f..db26fe6 100644
--- a/src/test/java/com/android/tools/r8/AsmTestBase.java
+++ b/src/test/java/com/android/tools/r8/AsmTestBase.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import java.io.IOException;
@@ -32,9 +33,10 @@
exceptionClass);
}
- protected void ensureSameOutput(String main, int apiLevel, byte[]... classes) throws Exception {
+ protected void ensureSameOutput(String main, AndroidApiLevel apiLevel, byte[]... classes)
+ throws Exception {
AndroidApp app = buildAndroidApp(classes);
- Consumer<InternalOptions> setMinApiLevel = o -> o.minApiLevel = apiLevel;
+ Consumer<InternalOptions> setMinApiLevel = o -> o.minApiLevel = apiLevel.getLevel();
ProcessResult javaResult = runOnJava(main, classes);
ProcessResult d8Result = runOnArtRaw(compileWithD8(app, setMinApiLevel), main);
ProcessResult r8Result = runOnArtRaw(compileWithR8(app, setMinApiLevel), main);
diff --git a/src/test/java/com/android/tools/r8/D8ApiBinaryCompatibilityTests.java b/src/test/java/com/android/tools/r8/D8ApiBinaryCompatibilityTests.java
index 4cde5d9..6d0ef5a 100644
--- a/src/test/java/com/android/tools/r8/D8ApiBinaryCompatibilityTests.java
+++ b/src/test/java/com/android/tools/r8/D8ApiBinaryCompatibilityTests.java
@@ -65,7 +65,8 @@
"--main-dex-list",
mainDexList.toString(),
"--lib",
- ToolHelper.getAndroidJar(minApiLevel).toString(),
+ ToolHelper.getAndroidJar(
+ AndroidApiLevel.getAndroidApiLevel(minApiLevel)).toString(),
"--classpath",
lib1.toString(),
"--classpath",
diff --git a/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
index 05d303c..caa1d48 100644
--- a/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
import com.android.tools.r8.ir.desugar.LambdaRewriter;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.OffOrAuto;
@@ -49,8 +50,8 @@
}
@Override
- D8IncrementalTestRunner withMinApiLevel(int minApiLevel) {
- return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel));
+ D8IncrementalTestRunner withMinApiLevel(AndroidApiLevel minApiLevel) {
+ return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel.getLevel()));
}
@Override
@@ -175,8 +176,8 @@
} else {
throw new Unreachable("Unexpected output mode " + outputMode);
}
- addLibraryReference(builder, ToolHelper
- .getAndroidJar(androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion));
+ addLibraryReference(builder, ToolHelper.getAndroidJar(
+ androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion.getLevel()));
try {
return ToolHelper.runD8(builder, this::combinedOptionConsumer);
} catch (Unimplemented | CompilationError | InternalCompilerError re) {
@@ -324,7 +325,7 @@
@Override
protected Path buildDexThroughIntermediate(String packageName, Path input, OutputMode outputMode,
- int minApi, String... mainDexClasses) throws Throwable {
+ AndroidApiLevel minApi, String... mainDexClasses) throws Throwable {
// tests using this should already been skipped.
throw new Unreachable();
}
diff --git a/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
index 832a781..dc4a9b4 100644
--- a/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
@@ -66,7 +66,7 @@
@Test
public void dexPerClassFileWithDesugaringAndFolderClasspath() throws Throwable {
- int minAPILevel = AndroidApiLevel.K.getLevel();
+ AndroidApiLevel minAPILevel = AndroidApiLevel.K;
Path inputFile =
Paths.get(ToolHelper.EXAMPLES_ANDROID_N_BUILD_DIR, "interfacemethods" + JAR_EXTENSION);
Path tmpClassesDir = temp.newFolder().toPath();
@@ -78,7 +78,7 @@
{
D8Command.Builder command =
D8Command.builder()
- .setMinApiLevel(minAPILevel)
+ .setMinApiLevel(minAPILevel.getLevel())
.addLibraryFiles(androidJar)
.addProgramFiles(inputFile);
@@ -98,7 +98,7 @@
for (Path classFile : individualClassFiles) {
D8Command.Builder builder =
D8Command.builder()
- .setMinApiLevel(minAPILevel)
+ .setMinApiLevel(minAPILevel.getLevel())
.addLibraryFiles(androidJar)
.addClasspathFiles(tmpClassesDir)
.addProgramFiles(classFile);
@@ -111,7 +111,7 @@
});
individalDexes.add(individualResult.getDexProgramResourcesForTesting().get(0));
}
- AndroidApp mergedResult = mergeDexResources(minAPILevel, individalDexes);
+ AndroidApp mergedResult = mergeDexResources(minAPILevel.getLevel(), individalDexes);
assertTrue(Arrays.equals(
readResource(fullBuildResult.getDexProgramResourcesForTesting().get(0)),
diff --git a/src/test/java/com/android/tools/r8/D8NonLazyRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8NonLazyRunExamplesAndroidOTest.java
index 905d209..e16ecd1 100644
--- a/src/test/java/com/android/tools/r8/D8NonLazyRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8NonLazyRunExamplesAndroidOTest.java
@@ -22,8 +22,8 @@
@Override
void addLibraryReference(D8Command.Builder builder, Path location) throws IOException {
- builder.addLibraryFiles(ToolHelper
- .getAndroidJar(androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion));
+ builder.addLibraryFiles(ToolHelper.getAndroidJar(
+ androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion.getLevel()));
}
@Override
diff --git a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
index edb73f7..b5802f4 100644
--- a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
@@ -27,8 +27,8 @@
}
@Override
- D8TestRunner withMinApiLevel(int minApiLevel) {
- return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel));
+ D8TestRunner withMinApiLevel(AndroidApiLevel minApiLevel) {
+ return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel.getLevel()));
}
D8TestRunner withClasspath(Path... classpath) {
@@ -43,7 +43,7 @@
}
builder.addLibraryFiles(
ToolHelper.getAndroidJar(
- androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion));
+ androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion.getLevel()));
builder.addProgramFiles(inputFile);
try {
ToolHelper.runD8(builder, this::combinedOptionConsumer);
@@ -70,7 +70,7 @@
D8TestRunner lib1 =
test("testDefaultInInterfaceWithoutDesugaring", "desugaringwithmissingclasslib1", "N/A")
.withInterfaceMethodDesugaring(OffOrAuto.Off)
- .withMinApiLevel(AndroidApiLevel.K.getLevel());
+ .withMinApiLevel(AndroidApiLevel.K);
try {
lib1.build();
@@ -87,7 +87,7 @@
D8TestRunner lib1 =
test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
.withInterfaceMethodDesugaring(OffOrAuto.Auto)
- .withMinApiLevel(AndroidApiLevel.K.getLevel());
+ .withMinApiLevel(AndroidApiLevel.K);
lib1.build();
// lib2: interface B extends A { default String foo() { return "B"; } }
@@ -96,7 +96,7 @@
test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
.withInterfaceMethodDesugaring(OffOrAuto.Auto)
.withClasspath(lib1.getInputJar())
- .withMinApiLevel(AndroidApiLevel.K.getLevel());
+ .withMinApiLevel(AndroidApiLevel.K);
lib2.build();
// test: class ImplementMethodsWithDefault implements A, B {} should get its foo implementation
@@ -107,7 +107,7 @@
test("desugaringwithmissingclasstest1", "desugaringwithmissingclasstest1", "N/A")
.withInterfaceMethodDesugaring(OffOrAuto.Auto)
.withClasspath(lib1.getInputJar())
- .withMinApiLevel(AndroidApiLevel.K.getLevel());
+ .withMinApiLevel(AndroidApiLevel.K);
test.build();
// TODO check compilation warnings are correctly reported
@@ -116,7 +116,7 @@
@Test
public void testMissingInterfaceDesugared2AndroidK() throws Throwable {
- int minApi = AndroidApiLevel.K.getLevel();
+ AndroidApiLevel minApi = AndroidApiLevel.K;
// lib1: interface A { default String foo() { return "A"; } }
D8TestRunner lib1 =
@@ -170,7 +170,7 @@
@Test
public void testMissingInterfaceDesugared2AndroidO() throws Throwable {
- int minApi = AndroidApiLevel.O.getLevel();
+ AndroidApiLevel minApi = AndroidApiLevel.O;
// lib1: interface A { default String foo() { return "A"; } }
D8TestRunner lib1 =
test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
@@ -218,7 +218,7 @@
@Test
public void testCallToMissingSuperInterfaceDesugaredAndroidK() throws Throwable {
- int minApi = AndroidApiLevel.K.getLevel();
+ AndroidApiLevel minApi = AndroidApiLevel.K;
// lib1: interface A { default String foo() { return "A"; } }
D8TestRunner lib1 =
test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
@@ -271,7 +271,7 @@
@Test
public void testCallToMissingSuperInterfaceDesugaredAndroidO() throws Throwable {
- int minApi = AndroidApiLevel.O.getLevel();
+ AndroidApiLevel minApi = AndroidApiLevel.O;
// lib1: interface A { default String foo() { return "A"; } }
D8TestRunner lib1 =
test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
@@ -318,7 +318,7 @@
@Test
public void testMissingSuperDesugaredAndroidK() throws Throwable {
- int minApi = AndroidApiLevel.K.getLevel();
+ AndroidApiLevel minApi = AndroidApiLevel.K;
// lib1: interface A { default String foo() { return "A"; } }
D8TestRunner lib1 =
@@ -366,7 +366,7 @@
@Test
public void testMissingSuperDesugaredAndroidO() throws Throwable {
- int minApi = AndroidApiLevel.O.getLevel();
+ AndroidApiLevel minApi = AndroidApiLevel.O;
// lib1: interface A { default String foo() { return "A"; } }
D8TestRunner lib1 =
@@ -416,7 +416,7 @@
@Test
public void testMissingSuperDesugaredWithProgramCrossImplementationAndroidK() throws Throwable {
- int minApi = AndroidApiLevel.K.getLevel();
+ AndroidApiLevel minApi = AndroidApiLevel.K;
// lib1: interface A { default String foo() { return "A"; } }
// interface A2 { default String foo2() { return "A2"; } }
@@ -461,7 +461,7 @@
@Test
public void testMissingSuperDesugaredWithClasspathCrossImplementationAndroidK() throws Throwable {
- int minApi = AndroidApiLevel.K.getLevel();
+ AndroidApiLevel minApi = AndroidApiLevel.K;
// lib1: interface A { default String foo() { return "A"; } }
// interface A2 { default String foo2() { return "A2"; } }
diff --git a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidPTest.java b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidPTest.java
index b8e9675..0ae485a 100644
--- a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidPTest.java
+++ b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidPTest.java
@@ -37,7 +37,7 @@
}
// TODO(mikaelpeltier) Add new android.jar build from aosp and use it
builder
- .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.O.getLevel()))
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.O))
.addProgramFiles(inputFile)
.setOutput(out, OutputMode.DexIndexed);
try {
diff --git a/src/test/java/com/android/tools/r8/D8RunExamplesJava9Test.java b/src/test/java/com/android/tools/r8/D8RunExamplesJava9Test.java
index 71ffde2..ece7f31 100644
--- a/src/test/java/com/android/tools/r8/D8RunExamplesJava9Test.java
+++ b/src/test/java/com/android/tools/r8/D8RunExamplesJava9Test.java
@@ -37,7 +37,7 @@
}
// TODO(mikaelpeltier) Add new android.jar build from aosp and use it
builder
- .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P.getLevel()))
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
.addProgramFiles(inputFile)
.setOutput(out, OutputMode.DexIndexed);
try {
diff --git a/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java b/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
index 8e8ca36..6533e08 100644
--- a/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
@@ -8,6 +8,7 @@
import static org.junit.Assert.assertFalse;
import com.android.tools.r8.naming.ProguardMapSupplier;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.VersionProperties;
import java.nio.file.Paths;
import java.util.HashSet;
@@ -17,15 +18,15 @@
public class ProguardMapMarkerTest {
@Test
public void proguardMapMarkerTest24() throws CompilationFailedException {
- proguardMapMarkerTest(24);
+ proguardMapMarkerTest(AndroidApiLevel.N);
}
@Test
public void proguardMapMarkerTest26() throws CompilationFailedException {
- proguardMapMarkerTest(26);
+ proguardMapMarkerTest(AndroidApiLevel.O);
}
- private void proguardMapMarkerTest(int minApiLevel) throws CompilationFailedException {
+ private void proguardMapMarkerTest(AndroidApiLevel minApiLevel) throws CompilationFailedException {
String classFile = ToolHelper.EXAMPLES_BUILD_DIR + "classes/trivial/Trivial.class";
R8.run(
R8Command.builder()
@@ -43,10 +44,10 @@
public void finished(DiagnosticsHandler handler) {}
})
.addLibraryFiles(ToolHelper.getAndroidJar(minApiLevel))
- .setMinApiLevel(minApiLevel)
+ .setMinApiLevel(minApiLevel.getLevel())
.setProguardMapConsumer(
(proguardMap, handler) -> {
- verifyMarkers(proguardMap, minApiLevel);
+ verifyMarkers(proguardMap, minApiLevel.getLevel());
})
.build());
}
diff --git a/src/test/java/com/android/tools/r8/R8ApiBinaryCompatibilityTests.java b/src/test/java/com/android/tools/r8/R8ApiBinaryCompatibilityTests.java
index 59536de..28fe5dc 100644
--- a/src/test/java/com/android/tools/r8/R8ApiBinaryCompatibilityTests.java
+++ b/src/test/java/com/android/tools/r8/R8ApiBinaryCompatibilityTests.java
@@ -22,7 +22,7 @@
static final Path JAR = Paths.get("tests", "r8_api_usage_sample.jar");
static final String MAIN = "com.android.tools.apiusagesample.R8ApiUsageSample";
- static final int MIN_API = AndroidApiLevel.K.getLevel();
+ static final AndroidApiLevel MIN_API = AndroidApiLevel.K;
@Rule public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();
@@ -54,7 +54,7 @@
"--output",
temp.newFolder().toString(),
"--min-api",
- Integer.toString(MIN_API),
+ Integer.toString(MIN_API.getLevel()),
"--pg-conf",
pgConf.toString(),
"--main-dex-rules",
diff --git a/src/test/java/com/android/tools/r8/R8IgnoreMissingClassesTest.java b/src/test/java/com/android/tools/r8/R8IgnoreMissingClassesTest.java
index 697158a..83bc302 100644
--- a/src/test/java/com/android/tools/r8/R8IgnoreMissingClassesTest.java
+++ b/src/test/java/com/android/tools/r8/R8IgnoreMissingClassesTest.java
@@ -4,6 +4,7 @@
package com.android.tools.r8;
import com.android.tools.r8.origin.EmbeddedOrigin;
+import com.android.tools.r8.utils.AndroidApiLevel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
@@ -11,14 +12,14 @@
public class R8IgnoreMissingClassesTest {
- private static final int MIN_API = 26;
+ private static final AndroidApiLevel MIN_API = AndroidApiLevel.O;
private static final Path EXAMPLE = Paths.get(ToolHelper.EXAMPLES_BUILD_DIR, "usestdlib.jar");
private static final Path LIBRARY = ToolHelper.getAndroidJar(MIN_API);
private R8Command.Builder config() {
return R8Command.builder()
.addProgramFiles(EXAMPLE)
- .setMinApiLevel(MIN_API)
+ .setMinApiLevel(MIN_API.getLevel())
.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
}
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index 2278d67..8cd4323 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -105,46 +105,46 @@
"third_party/gradle/gradle/lib/plugins/hamcrest-core-1.3.jar";
// Test that required to set min-api to a specific value.
- private static Map<String, Integer> needMinSdkVersion =
- new ImmutableMap.Builder<String, Integer>()
+ private static Map<String, AndroidApiLevel> needMinSdkVersion =
+ new ImmutableMap.Builder<String, AndroidApiLevel>()
// Android O
- .put("952-invoke-custom", AndroidApiLevel.O.getLevel())
- .put("952-invoke-custom-kinds", AndroidApiLevel.O.getLevel())
- .put("953-invoke-polymorphic-compiler", AndroidApiLevel.O.getLevel())
- .put("957-methodhandle-transforms", AndroidApiLevel.O.getLevel())
- .put("958-methodhandle-stackframe", AndroidApiLevel.O.getLevel())
- .put("959-invoke-polymorphic-accessors", AndroidApiLevel.O.getLevel())
- .put("979-const-method-handle", AndroidApiLevel.P.getLevel())
- .put("990-method-handle-and-mr", AndroidApiLevel.O.getLevel())
+ .put("952-invoke-custom", AndroidApiLevel.O)
+ .put("952-invoke-custom-kinds", AndroidApiLevel.O)
+ .put("953-invoke-polymorphic-compiler", AndroidApiLevel.O)
+ .put("957-methodhandle-transforms", AndroidApiLevel.O)
+ .put("958-methodhandle-stackframe", AndroidApiLevel.O)
+ .put("959-invoke-polymorphic-accessors", AndroidApiLevel.O)
+ .put("979-const-method-handle", AndroidApiLevel.P)
+ .put("990-method-handle-and-mr", AndroidApiLevel.O)
// Test intentionally asserts presence of bridge default methods desugar removes.
- .put("044-proxy", AndroidApiLevel.N.getLevel())
+ .put("044-proxy", AndroidApiLevel.N)
// Test intentionally asserts absence of default interface method in a class.
- .put("048-reflect-v8", AndroidApiLevel.N.getLevel())
+ .put("048-reflect-v8", AndroidApiLevel.N)
// Uses default interface methods.
- .put("162-method-resolution", AndroidApiLevel.N.getLevel())
- .put("616-cha-interface-default", AndroidApiLevel.N.getLevel())
- .put("1910-transform-with-default", AndroidApiLevel.N.getLevel())
+ .put("162-method-resolution", AndroidApiLevel.N)
+ .put("616-cha-interface-default", AndroidApiLevel.N)
+ .put("1910-transform-with-default", AndroidApiLevel.N)
// Interface initializer is not triggered after desugaring.
- .put("962-iface-static", AndroidApiLevel.N.getLevel())
+ .put("962-iface-static", AndroidApiLevel.N)
// Interface initializer is not triggered after desugaring.
- .put("964-default-iface-init-gen", AndroidApiLevel.N.getLevel())
+ .put("964-default-iface-init-gen", AndroidApiLevel.N)
// AbstractMethodError (for method not implemented in class) instead of
// IncompatibleClassChangeError (for conflict of default interface methods).
- .put("968-default-partial-compile-gen", AndroidApiLevel.N.getLevel())
+ .put("968-default-partial-compile-gen", AndroidApiLevel.N)
// NoClassDefFoundError (for companion class) instead of NoSuchMethodError.
- .put("970-iface-super-resolution-gen", AndroidApiLevel.N.getLevel())
+ .put("970-iface-super-resolution-gen", AndroidApiLevel.N)
// NoClassDefFoundError (for companion class) instead of AbstractMethodError.
- .put("971-iface-super", AndroidApiLevel.N.getLevel())
+ .put("971-iface-super", AndroidApiLevel.N)
// Test for miranda methods is not relevant for desugaring scenario.
- .put("972-default-imt-collision", AndroidApiLevel.N.getLevel())
+ .put("972-default-imt-collision", AndroidApiLevel.N)
// Uses default interface methods.
- .put("972-iface-super-multidex", AndroidApiLevel.N.getLevel())
+ .put("972-iface-super-multidex", AndroidApiLevel.N)
// java.util.Objects is missing and test has default methods.
- .put("973-default-multidex", AndroidApiLevel.N.getLevel())
+ .put("973-default-multidex", AndroidApiLevel.N)
// a.klass.that.does.not.Exist is missing and test has default methods.
- .put("974-verify-interface-super", AndroidApiLevel.N.getLevel())
+ .put("974-verify-interface-super", AndroidApiLevel.N)
// Desugaring of interface private methods is not yet supported.
- .put("975-iface-private", AndroidApiLevel.N.getLevel())
+ .put("975-iface-private", AndroidApiLevel.N)
.build();
// Tests that timeout when run with Art.
@@ -1390,13 +1390,13 @@
.setMode(mode)
.addProgramFiles(ListUtils.map(fileNames, Paths::get))
.setOutput(Paths.get(resultPath), OutputMode.DexIndexed);
- Integer minSdkVersion = needMinSdkVersion.get(name);
+ AndroidApiLevel minSdkVersion = needMinSdkVersion.get(name);
if (minSdkVersion != null) {
- builder.setMinApiLevel(minSdkVersion);
+ builder.setMinApiLevel(minSdkVersion.getLevel());
builder.addLibraryFiles(ToolHelper.getAndroidJar(minSdkVersion));
} else {
builder
- .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.getDefault().getLevel()));
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.getDefault()));
}
D8.run(builder.build());
break;
@@ -1409,12 +1409,12 @@
.setOutput(Paths.get(resultPath), OutputMode.DexIndexed);
// Add program files directly to the underlying app to avoid errors on DEX inputs.
ToolHelper.getAppBuilder(builder).addProgramFiles(ListUtils.map(fileNames, Paths::get));
- Integer minSdkVersion = needMinSdkVersion.get(name);
+ AndroidApiLevel minSdkVersion = needMinSdkVersion.get(name);
if (minSdkVersion != null) {
- builder.setMinApiLevel(minSdkVersion);
+ builder.setMinApiLevel(minSdkVersion.getLevel());
ToolHelper.addFilteredAndroidJar(builder, minSdkVersion);
} else {
- ToolHelper.addFilteredAndroidJar(builder, AndroidApiLevel.getDefault().getLevel());
+ ToolHelper.addFilteredAndroidJar(builder, AndroidApiLevel.getDefault());
}
if (keepRulesFile != null) {
builder.addProguardConfigurationFiles(Paths.get(keepRulesFile));
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
index 751c34e..b6b9ba8 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
@@ -48,7 +48,7 @@
@Test
public void invokeCustomWithShrinking() throws Throwable {
test("invokecustom-with-shrinking", "invokecustom", "InvokeCustom")
- .withMinApiLevel(AndroidApiLevel.O.getLevel())
+ .withMinApiLevel(AndroidApiLevel.O)
.withBuilderTransformation(builder ->
builder.addProguardConfigurationFiles(
Paths.get(ToolHelper.EXAMPLES_ANDROID_O_DIR, "invokecustom/keep-rules.txt")))
@@ -62,8 +62,8 @@
}
@Override
- R8TestRunner withMinApiLevel(int minApiLevel) {
- return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel));
+ R8TestRunner withMinApiLevel(AndroidApiLevel minApiLevel) {
+ return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel.getLevel()));
}
@Override
@@ -72,8 +72,8 @@
for (UnaryOperator<R8Command.Builder> transformation : builderTransformations) {
builder = transformation.apply(builder);
}
- builder.addLibraryFiles(ToolHelper
- .getAndroidJar(androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion));
+ builder.addLibraryFiles(ToolHelper.getAndroidJar(
+ androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion.getLevel()));
R8Command command = builder.addProgramFiles(inputFile).build();
ToolHelper.runR8(command, this::combinedOptionConsumer);
}
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidPTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidPTest.java
index becfa6d..f4665a9 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidPTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidPTest.java
@@ -72,7 +72,7 @@
builder = transformation.apply(builder);
}
// TODO(mikaelpeltier) Add new android.jar build from aosp and use it
- builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.O.getLevel()));
+ builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.O));
R8Command command =
builder.addProgramFiles(inputFile).setOutput(out, OutputMode.DexIndexed).build();
ToolHelper.runR8(command, this::combinedOptionConsumer);
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesJava9Test.java b/src/test/java/com/android/tools/r8/R8RunExamplesJava9Test.java
index 1a307a5..670e6be 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesJava9Test.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesJava9Test.java
@@ -28,7 +28,7 @@
builder = transformation.apply(builder);
}
// TODO(mikaelpeltier) Add new android.jar build from aosp and use it
- builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P.getLevel()));
+ builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P));
R8Command command =
builder.addProgramFiles(inputFile).setOutput(out, OutputMode.DexIndexed).build();
ToolHelper.runR8(command, this::combinedOptionConsumer);
diff --git a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
index fa507b0..1bbcfdc 100644
--- a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
@@ -57,7 +57,7 @@
final String packageName;
final String mainClass;
- Integer androidJarVersion = null;
+ AndroidApiLevel androidJarVersion = null;
final List<Consumer<InternalOptions>> optionConsumers = new ArrayList<>();
final List<Consumer<DexInspector>> dexInspectorChecks = new ArrayList<>();
@@ -162,9 +162,9 @@
execute(testName, qualifiedMainClass, new Path[]{inputFile}, new Path[]{out});
}
- abstract C withMinApiLevel(int minApiLevel);
+ abstract C withMinApiLevel(AndroidApiLevel minApiLevel);
- C withAndroidJar(int androidJarVersion) {
+ C withAndroidJar(AndroidApiLevel androidJarVersion) {
assert this.androidJarVersion == null;
this.androidJarVersion = androidJarVersion;
return self();
@@ -291,56 +291,56 @@
@Test
public void stringConcat() throws Throwable {
test("stringconcat", "stringconcat", "StringConcat")
- .withMinApiLevel(AndroidApiLevel.K.getLevel())
+ .withMinApiLevel(AndroidApiLevel.K)
.run();
}
@Test
public void invokeCustom() throws Throwable {
test("invokecustom", "invokecustom", "InvokeCustom")
- .withMinApiLevel(AndroidApiLevel.O.getLevel())
+ .withMinApiLevel(AndroidApiLevel.O)
.run();
}
@Test
public void invokeCustom2() throws Throwable {
test("invokecustom2", "invokecustom2", "InvokeCustom")
- .withMinApiLevel(AndroidApiLevel.O.getLevel())
+ .withMinApiLevel(AndroidApiLevel.O)
.run();
}
@Test
public void invokeCustomErrorDueToMinSdk() throws Throwable {
test("invokecustom-error-due-to-min-sdk", "invokecustom", "InvokeCustom")
- .withMinApiLevel(25)
+ .withMinApiLevel(AndroidApiLevel.N_MR1)
.run();
}
@Test
public void invokePolymorphic() throws Throwable {
test("invokepolymorphic", "invokepolymorphic", "InvokePolymorphic")
- .withMinApiLevel(AndroidApiLevel.O.getLevel())
+ .withMinApiLevel(AndroidApiLevel.O)
.run();
}
@Test
public void invokePolymorphicErrorDueToMinSdk() throws Throwable {
test("invokepolymorphic-error-due-to-min-sdk", "invokepolymorphic", "InvokePolymorphic")
- .withMinApiLevel(25)
+ .withMinApiLevel(AndroidApiLevel.N_MR1)
.run();
}
@Test
public void lambdaDesugaring() throws Throwable {
test("lambdadesugaring", "lambdadesugaring", "LambdaDesugaring")
- .withMinApiLevel(AndroidApiLevel.K.getLevel())
+ .withMinApiLevel(AndroidApiLevel.K)
.run();
}
@Test
public void lambdaDesugaringNPlus() throws Throwable {
test("lambdadesugaringnplus", "lambdadesugaringnplus", "LambdasWithStaticAndDefaultMethods")
- .withMinApiLevel(AndroidApiLevel.K.getLevel())
+ .withMinApiLevel(AndroidApiLevel.K)
.withInterfaceMethodDesugaring(OffOrAuto.Auto)
.run();
}
@@ -348,8 +348,8 @@
@Test
public void desugarDefaultMethodInAndroidJar25() throws Throwable {
test("DefaultMethodInAndroidJar25", "desugaringwithandroidjar25", "DefaultMethodInAndroidJar25")
- .withMinApiLevel(AndroidApiLevel.K.getLevel())
- .withAndroidJar(AndroidApiLevel.O.getLevel())
+ .withMinApiLevel(AndroidApiLevel.K)
+ .withAndroidJar(AndroidApiLevel.O)
.withInterfaceMethodDesugaring(OffOrAuto.Auto)
.run();
}
@@ -357,8 +357,8 @@
@Test
public void desugarStaticMethodInAndroidJar25() throws Throwable {
test("StaticMethodInAndroidJar25", "desugaringwithandroidjar25", "StaticMethodInAndroidJar25")
- .withMinApiLevel(AndroidApiLevel.K.getLevel())
- .withAndroidJar(AndroidApiLevel.O.getLevel())
+ .withMinApiLevel(AndroidApiLevel.K)
+ .withAndroidJar(AndroidApiLevel.O)
.withInterfaceMethodDesugaring(OffOrAuto.Auto)
.run();
}
@@ -366,14 +366,14 @@
@Test
public void lambdaDesugaringValueAdjustments() throws Throwable {
test("lambdadesugaring-value-adjustments", "lambdadesugaring", "ValueAdjustments")
- .withMinApiLevel(AndroidApiLevel.K.getLevel())
+ .withMinApiLevel(AndroidApiLevel.K)
.run();
}
@Test
public void paramNames() throws Throwable {
test("paramnames", "paramnames", "ParameterNames")
- .withMinApiLevel(AndroidApiLevel.O.getLevel())
+ .withMinApiLevel(AndroidApiLevel.O)
.run();
}
@@ -469,7 +469,7 @@
int expectedMainDexListSize,
String... mainDexClasses)
throws Throwable {
- int minApi = AndroidApiLevel.K.getLevel();
+ AndroidApiLevel minApi = AndroidApiLevel.K;
// Full build, will be used as reference.
TestRunner<?> full =
@@ -514,7 +514,7 @@
String packageName,
Path input,
OutputMode outputMode,
- int minApi,
+ AndroidApiLevel minApi,
String... mainDexClasses)
throws Throwable {
Path intermediateDex =
@@ -522,7 +522,7 @@
// Build intermediate with D8.
D8Command.Builder command = D8Command.builder()
.setOutput(intermediateDex, outputMode)
- .setMinApiLevel(minApi)
+ .setMinApiLevel(minApi.getLevel())
.addLibraryFiles(ToolHelper.getAndroidJar(minApi))
.setIntermediate(true)
.addProgramFiles(input);
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 500b55c..77f9ad9 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -113,9 +113,7 @@
protected static AndroidApp readClassesAndAndriodJar(List<Class> programClasses)
throws IOException {
- return readClassesAndAndriodJar(programClasses,
- AndroidApiLevel.getAndroidApiLevel(
- ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm())));
+ return readClassesAndAndriodJar(programClasses, ToolHelper.getMinApiLevelForDexVm());
}
protected static AndroidApp readClassesAndAndriodJar(
@@ -125,7 +123,7 @@
for (Class clazz : programClasses) {
builder.addProgramFiles(ToolHelper.getClassFileForTestClass(clazz));
}
- builder.addLibraryFiles(ToolHelper.getAndroidJar(androidLibrary.getLevel()));
+ builder.addLibraryFiles(ToolHelper.getAndroidJar(androidLibrary));
return builder.build();
}
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 83cc931..d9f10ae 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -88,7 +88,7 @@
public static final String DEFAULT_PROGUARD_MAP_FILE = "proguard.map";
private static final String ANDROID_JAR_PATTERN = "third_party/android_jar/lib-v%d/android.jar";
- private static final int DEFAULT_MIN_SDK = AndroidApiLevel.I.getLevel();
+ private static final AndroidApiLevel DEFAULT_MIN_SDK = AndroidApiLevel.I;
private static final String PROGUARD = "third_party/proguard/proguard5.2.1/bin/proguard.sh";
@@ -483,32 +483,36 @@
}
public static Path getDefaultAndroidJar() {
- return getAndroidJar(AndroidApiLevel.getDefault().getLevel());
+ return getAndroidJar(AndroidApiLevel.getDefault());
}
- public static Path getAndroidJar(int minSdkVersion) {
- if (minSdkVersion == AndroidApiLevel.P.getLevel()) {
+ public static Path getAndroidJar(int apiLevel) {
+ return getAndroidJar(AndroidApiLevel.getAndroidApiLevel(apiLevel));
+ }
+
+ public static Path getAndroidJar(AndroidApiLevel apiLevel) {
+ if (apiLevel == AndroidApiLevel.P) {
// TODO(mikaelpeltier) Android P does not yet have his android.jar use the O version
- minSdkVersion = AndroidApiLevel.O.getLevel();
+ apiLevel = AndroidApiLevel.O;
}
String jar = String.format(
ANDROID_JAR_PATTERN,
- minSdkVersion == AndroidApiLevel.getDefault().getLevel() ? DEFAULT_MIN_SDK : minSdkVersion);
+ (apiLevel == AndroidApiLevel.getDefault() ? DEFAULT_MIN_SDK : apiLevel).getLevel());
assert Files.exists(Paths.get(jar))
- : "Expected android jar to exist for API level " + minSdkVersion;
+ : "Expected android jar to exist for API level " + apiLevel;
return Paths.get(jar);
}
- public static Path getJdwpTestsCfJarPath(int minSdk) {
- if (minSdk >= AndroidApiLevel.N.getLevel()) {
+ public static Path getJdwpTestsCfJarPath(AndroidApiLevel minSdk) {
+ if (minSdk.getLevel() >= AndroidApiLevel.N.getLevel()) {
return Paths.get("third_party", "jdwp-tests", "apache-harmony-jdwp-tests-host.jar");
} else {
return Paths.get(ToolHelper.BUILD_DIR, "libs", "jdwp-tests-preN.jar");
}
}
- public static Path getJdwpTestsDexJarPath(int minSdk) {
- if (minSdk >= AndroidApiLevel.N.getLevel()) {
+ public static Path getJdwpTestsDexJarPath(AndroidApiLevel minSdk) {
+ if (minSdk.getLevel() >= AndroidApiLevel.N.getLevel()) {
return Paths.get("third_party", "jdwp-tests", "apache-harmony-jdwp-tests-hostdex.jar");
} else {
return Paths.get(ToolHelper.BUILD_DIR, "libs", "jdwp-tests-preN-dex.jar");
@@ -593,20 +597,24 @@
}
}
- public static int getMinApiLevelForDexVm(DexVm dexVm) {
+ public static AndroidApiLevel getMinApiLevelForDexVm() {
+ return getMinApiLevelForDexVm(ToolHelper.getDexVm());
+ }
+
+ public static AndroidApiLevel getMinApiLevelForDexVm(DexVm dexVm) {
switch (dexVm.version) {
case DEFAULT:
- return AndroidApiLevel.O.getLevel();
+ return AndroidApiLevel.O;
case V7_0_0:
- return AndroidApiLevel.N.getLevel();
+ return AndroidApiLevel.N;
case V6_0_1:
- return AndroidApiLevel.M.getLevel();
+ return AndroidApiLevel.M;
case V5_1_1:
- return AndroidApiLevel.L_MR1.getLevel();
+ return AndroidApiLevel.L_MR1;
case V4_4_4:
- return AndroidApiLevel.K.getLevel();
+ return AndroidApiLevel.K;
case V4_0_4:
- return AndroidApiLevel.I_MR1.getLevel();
+ return AndroidApiLevel.I_MR1;
default:
throw new Unreachable("Missing min api level for dex vm " + dexVm);
}
@@ -780,7 +788,7 @@
// Add the android library matching the minsdk. We filter out junit and testing classes
// from the android jar to avoid duplicate classes in art and jctf tests.
AndroidApp.Builder builder = AndroidApp.builder(app);
- addFilteredAndroidJar(builder, command.getMinApiLevel());
+ addFilteredAndroidJar(builder, AndroidApiLevel.getAndroidApiLevel(command.getMinApiLevel()));
app = builder.build();
}
InternalOptions options = command.getInternalOptions();
@@ -792,15 +800,15 @@
return compatSink.build();
}
- public static void addFilteredAndroidJar(BaseCommand.Builder builder, int minSdkVersion)
+ public static void addFilteredAndroidJar(BaseCommand.Builder builder, AndroidApiLevel apiLevel)
throws IOException {
- addFilteredAndroidJar(getAppBuilder(builder), minSdkVersion);
+ addFilteredAndroidJar(getAppBuilder(builder), apiLevel);
}
- public static void addFilteredAndroidJar(AndroidApp.Builder builder, int minSdkVersion)
+ public static void addFilteredAndroidJar(AndroidApp.Builder builder, AndroidApiLevel apiLevel)
throws IOException {
builder.addFilteredLibraryArchives(Collections.singletonList(
- new FilteredClassPath(getAndroidJar(minSdkVersion),
+ new FilteredClassPath(getAndroidJar(apiLevel),
ImmutableList.of("!junit/**", "!android/test/**"))));
}
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/AccessRelaxationTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/AccessRelaxationTest.java
index 18e17f9..34b92b0 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/AccessRelaxationTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/AccessRelaxationTest.java
@@ -25,7 +25,7 @@
R8Command.Builder builder = R8Command.builder();
builder.addProgramFiles(ToolHelper.getClassFilesForTestPackage(A.class.getPackage()));
builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
- builder.setMinApiLevel(ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm()));
+ builder.setMinApiLevel(ToolHelper.getMinApiLevelForDexVm().getLevel());
// Note: we use '-checkdiscard' to indirectly check that the access relaxation is
// done which leads to inlining of all pB*** methods so they are removed. Without
diff --git a/src/test/java/com/android/tools/r8/debug/CfDebugTestConfig.java b/src/test/java/com/android/tools/r8/debug/CfDebugTestConfig.java
index 6049b7d..e8fa240 100644
--- a/src/test/java/com/android/tools/r8/debug/CfDebugTestConfig.java
+++ b/src/test/java/com/android/tools/r8/debug/CfDebugTestConfig.java
@@ -13,8 +13,7 @@
/** Base test configuration with CF version of JDWP. */
public class CfDebugTestConfig extends DebugTestConfig {
- public static final Path JDWP_JAR =
- ToolHelper.getJdwpTestsCfJarPath(AndroidApiLevel.N.getLevel());
+ public static final Path JDWP_JAR = ToolHelper.getJdwpTestsCfJarPath(AndroidApiLevel.N);
public CfDebugTestConfig() {
this(Collections.emptyList());
diff --git a/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java b/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java
index 8480d24..1f13006 100644
--- a/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java
+++ b/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.D8Command;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ListUtils;
@@ -21,12 +22,12 @@
public static AndroidApp d8Compile(List<Path> paths, Consumer<InternalOptions> optionsConsumer) {
try {
- int minSdk = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm());
+ AndroidApiLevel minSdk = ToolHelper.getMinApiLevelForDexVm();
D8Command.Builder builder = D8Command.builder();
return ToolHelper.runD8(
builder
.addProgramFiles(paths)
- .setMinApiLevel(minSdk)
+ .setMinApiLevel(minSdk.getLevel())
.setMode(CompilationMode.DEBUG)
.addLibraryFiles(ToolHelper.getAndroidJar(minSdk)),
optionsConsumer);
diff --git a/src/test/java/com/android/tools/r8/debug/DebugInfoWhenInliningTest.java b/src/test/java/com/android/tools/r8/debug/DebugInfoWhenInliningTest.java
index 3b7e4e8..6432530 100644
--- a/src/test/java/com/android/tools/r8/debug/DebugInfoWhenInliningTest.java
+++ b/src/test/java/com/android/tools/r8/debug/DebugInfoWhenInliningTest.java
@@ -8,10 +8,10 @@
import com.android.tools.r8.R8Command;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.Command;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -33,7 +33,7 @@
boolean writeProguardMap)
throws Exception {
assert outputMode == OutputMode.DexIndexed || outputMode == OutputMode.ClassFile;
- int minSdk = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm());
+ AndroidApiLevel minSdk = ToolHelper.getMinApiLevelForDexVm();
String prefix = outputMode == OutputMode.ClassFile ? "cf" : "dex";
Path outdir = temp.newFolder().toPath();
Path outjar = outdir.resolve(prefix + "_r8_compiled.jar");
@@ -41,7 +41,7 @@
R8Command.Builder builder =
R8Command.builder()
.addProgramFiles(DEBUGGEE_JAR)
- .setMinApiLevel(minSdk)
+ .setMinApiLevel(minSdk.getLevel())
.addLibraryFiles(ToolHelper.getAndroidJar(minSdk))
.setMode(CompilationMode.RELEASE)
.setOutput(outjar, outputMode);
diff --git a/src/test/java/com/android/tools/r8/debug/DebugTestBase.java b/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
index 94d5666..cbfcca6 100644
--- a/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
+++ b/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
@@ -115,7 +115,7 @@
protected static final boolean supportsDefaultMethod(DebugTestConfig config) {
return config.isCfRuntime()
- || ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm()) >= AndroidApiLevel.N.getLevel();
+ || ToolHelper.getMinApiLevelForDexVm().getLevel() >= AndroidApiLevel.N.getLevel();
}
protected final void runDebugTest(
diff --git a/src/test/java/com/android/tools/r8/debug/DexDebugTestConfig.java b/src/test/java/com/android/tools/r8/debug/DexDebugTestConfig.java
index 27e3d30..babf170 100644
--- a/src/test/java/com/android/tools/r8/debug/DexDebugTestConfig.java
+++ b/src/test/java/com/android/tools/r8/debug/DexDebugTestConfig.java
@@ -13,7 +13,7 @@
public class DexDebugTestConfig extends DebugTestConfig {
public static final Path JDWP_DEX_JAR =
- ToolHelper.getJdwpTestsDexJarPath(ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm()));
+ ToolHelper.getJdwpTestsDexJarPath(ToolHelper.getMinApiLevelForDexVm());
public DexDebugTestConfig() {
this(Collections.emptyList());
diff --git a/src/test/java/com/android/tools/r8/debug/LineNumberOptimizationTest.java b/src/test/java/com/android/tools/r8/debug/LineNumberOptimizationTest.java
index d7e4d25..e251662 100644
--- a/src/test/java/com/android/tools/r8/debug/LineNumberOptimizationTest.java
+++ b/src/test/java/com/android/tools/r8/debug/LineNumberOptimizationTest.java
@@ -7,9 +7,9 @@
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import java.nio.file.Path;
-import java.nio.file.Paths;
import org.junit.Test;
/** Tests source file and line numbers on inlined methods. */
@@ -31,14 +31,14 @@
boolean writeProguardMap,
boolean dontOptimizeByEnablingDebug)
throws Exception {
- int minSdk = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm());
+ AndroidApiLevel minSdk = ToolHelper.getMinApiLevelForDexVm();
Path outdir = temp.newFolder().toPath();
Path outjar = outdir.resolve("r8_compiled.jar");
Path proguardMapPath = writeProguardMap ? outdir.resolve("proguard.map") : null;
R8Command.Builder builder =
R8Command.builder()
.addProgramFiles(DEBUGGEE_JAR)
- .setMinApiLevel(minSdk)
+ .setMinApiLevel(minSdk.getLevel())
.addLibraryFiles(ToolHelper.getAndroidJar(minSdk))
.setMode(dontOptimizeByEnablingDebug ? CompilationMode.DEBUG : CompilationMode.RELEASE)
.setOutput(outjar, OutputMode.DexIndexed);
diff --git a/src/test/java/com/android/tools/r8/debug/MinificationTest.java b/src/test/java/com/android/tools/r8/debug/MinificationTest.java
index 7bf989c..5f63038 100644
--- a/src/test/java/com/android/tools/r8/debug/MinificationTest.java
+++ b/src/test/java/com/android/tools/r8/debug/MinificationTest.java
@@ -9,10 +9,10 @@
import com.android.tools.r8.TestBase.MinifyMode;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -68,14 +68,14 @@
proguardConfigurations = builder.build();
}
- int minSdk = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm());
+ AndroidApiLevel minSdk = ToolHelper.getMinApiLevelForDexVm();
Path dexOutputDir = temp.newFolder().toPath();
Path proguardMap = writeProguardMap ? dexOutputDir.resolve("proguard.map") : null;
R8Command.Builder builder =
R8Command.builder()
.addProgramFiles(DEBUGGEE_JAR)
.setOutput(dexOutputDir, OutputMode.DexIndexed)
- .setMinApiLevel(minSdk)
+ .setMinApiLevel(minSdk.getLevel())
.setMode(CompilationMode.DEBUG)
.addLibraryFiles(ToolHelper.getAndroidJar(minSdk));
if (proguardMap != null) {
diff --git a/src/test/java/com/android/tools/r8/debug/R8CfDebugTestResourcesConfig.java b/src/test/java/com/android/tools/r8/debug/R8CfDebugTestResourcesConfig.java
index d5bbe18..4916e1d 100644
--- a/src/test/java/com/android/tools/r8/debug/R8CfDebugTestResourcesConfig.java
+++ b/src/test/java/com/android/tools/r8/debug/R8CfDebugTestResourcesConfig.java
@@ -8,10 +8,10 @@
import com.android.tools.r8.R8;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
import java.nio.file.Path;
-import java.nio.file.Paths;
import org.junit.rules.TemporaryFolder;
// Shared test configuration for R8/CF compiled resources from the "debugTestResources" target.
@@ -21,11 +21,11 @@
private static synchronized AndroidApp getCompiledResources() throws Throwable {
if (compiledResources == null) {
- int minApi = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm());
+ AndroidApiLevel minApi = ToolHelper.getMinApiLevelForDexVm();
AndroidAppConsumers sink = new AndroidAppConsumers();
R8.run(
R8Command.builder()
- .setMinApiLevel(minApi)
+ .setMinApiLevel(minApi.getLevel())
.setMode(CompilationMode.DEBUG)
.addProgramFiles(DebugTestBase.DEBUGGEE_JAR)
.setProgramConsumer(sink.wrapClassFileConsumer(null))
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 ab5ce01..97047e8 100644
--- a/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
@@ -85,7 +85,7 @@
D8Command.builder()
.addClasspathFiles(classpath)
.addProgramFiles(toCompile)
- .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K.getLevel()))
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K))
.setMinApiLevel(AndroidApiLevel.K.getLevel()),
options -> options.interfaceMethodDesugaring = OffOrAuto.Auto);
}
@@ -99,7 +99,7 @@
D8Command.builder()
.addClasspathFiles(classpath)
.addProgramFiles(toCompile)
- .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K.getLevel()))
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K))
.setMinApiLevel(AndroidApiLevel.K.getLevel()),
options -> options.interfaceMethodDesugaring = OffOrAuto.Off);
}
diff --git a/src/test/java/com/android/tools/r8/jdwp/RunJdwpTests.java b/src/test/java/com/android/tools/r8/jdwp/RunJdwpTests.java
index 1349830..af8382e 100644
--- a/src/test/java/com/android/tools/r8/jdwp/RunJdwpTests.java
+++ b/src/test/java/com/android/tools/r8/jdwp/RunJdwpTests.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.io.File;
@@ -270,7 +271,7 @@
@BeforeClass
public static void compileLibraries() throws Exception {
// Selects appropriate jar according to min api level for the selected runtime.
- int minApi = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm());
+ AndroidApiLevel minApi = ToolHelper.getMinApiLevelForDexVm();
Path jdwpTestsJar = ToolHelper.getJdwpTestsCfJarPath(minApi);
Path classPath = ToolHelper.getClassPathForTests();
Path testPath = classPath.resolve(Paths.get("com","android", "tools", "r8", "jdwp"));
@@ -285,7 +286,7 @@
.addProgramFiles(jdwpTestsJar)
.addProgramFiles(extraTestResources)
.setOutput(d8Out.toPath(), OutputMode.DexIndexed)
- .setMinApiLevel(minApi)
+ .setMinApiLevel(minApi.getLevel())
.setMode(CompilationMode.DEBUG)
.build());
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java b/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java
index d79d099..15c20c5 100644
--- a/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java
+++ b/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java
@@ -24,7 +24,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
-import java.util.List;
import java.util.Map;
import org.junit.Assume;
@@ -90,17 +89,16 @@
return classSubject;
}
- private static MethodSubject checkMethod(ClassSubject classSubject, String methodName,
- String methodReturnType, List<String> methodParameterTypes, boolean isPresent) {
- return checkMethod(classSubject,
- new MethodSignature(methodName, methodReturnType, methodParameterTypes), isPresent);
- }
-
protected static MethodSubject checkMethodIsPresent(ClassSubject classSubject,
MethodSignature methodSignature) {
return checkMethod(classSubject, methodSignature, true);
}
+ protected static MethodSubject checkMethodIsAbsent(ClassSubject classSubject,
+ MethodSignature methodSignature) {
+ return checkMethod(classSubject, methodSignature, false);
+ }
+
protected static MethodSubject checkMethod(ClassSubject classSubject,
MethodSignature methodSignature, boolean isPresent) {
MethodSubject methodSubject = classSubject.method(methodSignature);
@@ -121,21 +119,6 @@
return code.asDexCode();
}
- private static DexCode extractCodeFor(DexInspector dexInspector, String className,
- String methodName,
- String methodReturnType, List<String> methodParameterTypes) {
- ClassSubject classSubject = checkClassExists(dexInspector, className);
- MethodSubject methodSubject = checkMethodIsPresent(classSubject, methodName, methodReturnType,
- methodParameterTypes);
- return getDexCode(methodSubject);
- }
-
- protected static MethodSubject checkMethodIsPresent(ClassSubject classSubject, String methodName,
- String methodReturnType,
- List<String> methodParameterTypes) {
- return checkMethod(classSubject, methodName, methodReturnType, methodParameterTypes, true);
- }
-
private String buildProguardRules(String mainClass) {
ProguardRulesBuilder proguardRules = new ProguardRulesBuilder();
proguardRules.appendWithLineSeparator(keepMainProguardConfiguration(mainClass));
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java
index 343fe9c..fe0efd1 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinDataClassTest.java
@@ -10,11 +10,8 @@
import com.android.tools.r8.utils.DexInspector.ClassSubject;
import com.android.tools.r8.utils.DexInspector.MethodSubject;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import java.util.Collection;
import java.util.Collections;
-import java.util.Map;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -61,17 +58,16 @@
// Getters should be removed after inlining, which is possible only if access is relaxed.
final boolean areGetterPresent = !allowAccessModification;
+ checkMethod(dataClass, NAME_GETTER_METHOD, areGetterPresent);
+ checkMethod(dataClass, AGE_GETTER_METHOD, areGetterPresent);
- Map<MethodSignature, Boolean> presenceMap = ImmutableMap.<MethodSignature, Boolean>builder()
- .put(NAME_GETTER_METHOD, areGetterPresent)
- .put(AGE_GETTER_METHOD, areGetterPresent)
- // ComponentN and copy methods are not used.
- .put(COMPONENT1_METHOD, false)
- .put(COMPONENT2_METHOD, false)
- .put(COPY_METHOD, false)
- .put(COPY_DEFAULT_METHOD, false)
- .build();
- checkMethodsPresence(dataClass, presenceMap);
+ // No use of componentN functions.
+ checkMethodIsAbsent(dataClass, COMPONENT1_METHOD);
+ checkMethodIsAbsent(dataClass, COMPONENT2_METHOD);
+
+ // No use of copy functions.
+ checkMethodIsAbsent(dataClass, COPY_METHOD);
+ checkMethodIsAbsent(dataClass, COPY_DEFAULT_METHOD);
ClassSubject classSubject = checkClassExists(dexInspector, mainClassName);
MethodSubject testMethod = checkMethodIsPresent(classSubject, testMethodSignature);
@@ -98,17 +94,16 @@
// ComponentN functions should be removed after inlining, which is possible only if access
// is relaxed.
final boolean areComponentMethodsPresent = !allowAccessModification;
+ checkMethod(dataClass, COMPONENT1_METHOD, areComponentMethodsPresent);
+ checkMethod(dataClass, COMPONENT2_METHOD, areComponentMethodsPresent);
- Map<MethodSignature, Boolean> presenceMap = ImmutableMap.<MethodSignature, Boolean>builder()
- .put(NAME_GETTER_METHOD, false)
- .put(AGE_GETTER_METHOD, false)
- // ComponentN and copy methods are not used.
- .put(COMPONENT1_METHOD, areComponentMethodsPresent)
- .put(COMPONENT2_METHOD, areComponentMethodsPresent)
- .put(COPY_METHOD, false)
- .put(COPY_DEFAULT_METHOD, false)
- .build();
- checkMethodsPresence(dataClass, presenceMap);
+ // No use of getter.
+ checkMethodIsAbsent(dataClass, NAME_GETTER_METHOD);
+ checkMethodIsAbsent(dataClass, AGE_GETTER_METHOD);
+
+ // No use of copy functions.
+ checkMethodIsAbsent(dataClass, COPY_METHOD);
+ checkMethodIsAbsent(dataClass, COPY_DEFAULT_METHOD);
ClassSubject classSubject = checkClassExists(dexInspector, mainClassName);
MethodSubject testMethod = checkMethodIsPresent(classSubject, testMethodSignature);
@@ -132,17 +127,18 @@
ClassSubject dataClass = checkClassExists(dexInspector, TEST_DATA_CLASS.getClassName());
boolean component2IsPresent = !allowAccessModification;
+ checkMethod(dataClass, COMPONENT2_METHOD, component2IsPresent);
- Map<MethodSignature, Boolean> presenceMap = ImmutableMap.<MethodSignature, Boolean>builder()
- .put(NAME_GETTER_METHOD, false)
- .put(AGE_GETTER_METHOD, false)
- // ComponentN and copy methods are not used.
- .put(COMPONENT1_METHOD, false)
- .put(COMPONENT2_METHOD, component2IsPresent)
- .put(COPY_METHOD, false)
- .put(COPY_DEFAULT_METHOD, false)
- .build();
- checkMethodsPresence(dataClass, presenceMap);
+ // Function component1 is not used.
+ checkMethodIsAbsent(dataClass, COMPONENT1_METHOD);
+
+ // No use of getter.
+ checkMethodIsAbsent(dataClass, NAME_GETTER_METHOD);
+ checkMethodIsAbsent(dataClass, AGE_GETTER_METHOD);
+
+ // No use of copy functions.
+ checkMethodIsAbsent(dataClass, COPY_METHOD);
+ checkMethodIsAbsent(dataClass, COPY_DEFAULT_METHOD);
ClassSubject classSubject = checkClassExists(dexInspector, mainClassName);
MethodSubject testMethod = checkMethodIsPresent(classSubject, testMethodSignature);
@@ -156,27 +152,23 @@
}
@Test
- public void test_dataclass_copy() throws Exception {
- final String mainClassName = "dataclass.MainCopyKt";
- runTest("dataclass", mainClassName, (app) -> {
+ public void test_dataclass_copyIsRemovedIfNotUsed() throws Exception {
+ final String mainClassName = "dataclass.MainComponentOnlyKt";
+ final MethodSignature testMethodSignature =
+ new MethodSignature("testDataClassCopy", "void", Collections.emptyList());
+ final String extraRules = keepClassMethod(mainClassName, testMethodSignature);
+ runTest("dataclass", mainClassName, extraRules, (app) -> {
DexInspector dexInspector = new DexInspector(app);
ClassSubject dataClass = checkClassExists(dexInspector, TEST_DATA_CLASS.getClassName());
- // Copy method is small enough that it is always inlined.
- final boolean copyMethodIsPresent = false;
-
- Map<MethodSignature, Boolean> presenceMap = ImmutableMap.<MethodSignature, Boolean>builder()
- .put(COPY_METHOD, copyMethodIsPresent)
- .put(COPY_DEFAULT_METHOD, false)
- .build();
- checkMethodsPresence(dataClass, presenceMap);
+ checkMethodIsAbsent(dataClass, COPY_METHOD);
+ checkMethodIsAbsent(dataClass, COPY_DEFAULT_METHOD);
});
}
@Test
- @Ignore("See b/72871423")
- public void test_dataclass_copyDefault() throws Exception {
- final String mainClassName = "dataclass.MainCopyWithDefaultKt";
+ public void test_dataclass_copyDefaultIsRemovedIfNotUsed() throws Exception {
+ final String mainClassName = "dataclass.MainCopyKt";
final MethodSignature testMethodSignature =
new MethodSignature("testDataClassCopyWithDefault", "void", Collections.emptyList());
final String extraRules = keepClassMethod(mainClassName, testMethodSignature);
@@ -184,30 +176,7 @@
DexInspector dexInspector = new DexInspector(app);
ClassSubject dataClass = checkClassExists(dexInspector, TEST_DATA_CLASS.getClassName());
- // Copy$default method is inlined if access is relaxed.
- final boolean copyDefaultMethodIsPresent = !allowAccessModification;
-
- // copy$default is a wrapper around copy to deal with default values. If it's inlined thus
- // copy is inlined as well.
- final boolean copyMethodIsPresent = copyDefaultMethodIsPresent;
-
- Map<MethodSignature, Boolean> presenceMap = ImmutableMap.<MethodSignature, Boolean>builder()
- .put(COPY_DEFAULT_METHOD, copyDefaultMethodIsPresent)
- .put(COPY_METHOD, copyMethodIsPresent)
- .build();
- checkMethodsPresence(dataClass, presenceMap);
-
- if (copyDefaultMethodIsPresent) {
- ClassSubject classSubject = checkClassExists(dexInspector, mainClassName);
- MethodSubject testMethod = checkMethodIsPresent(classSubject, testMethodSignature);
- DexCode dexCode = getDexCode(testMethod);
- checkMethodIsInvokedAtLeastOnce(dexCode, COPY_DEFAULT_METHOD);
- }
- if (copyMethodIsPresent) {
- MethodSubject testMethod = checkMethod(dataClass, COPY_DEFAULT_METHOD, true);
- DexCode dexCode = getDexCode(testMethod);
- checkMethodIsInvokedAtLeastOnce(dexCode, COPY_METHOD);
- }
+ checkMethodIsAbsent(dataClass, COPY_DEFAULT_METHOD);
});
}
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
index e33d785..57faa69 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
@@ -47,7 +47,7 @@
EXAMPLE_BUILD_DIR,
Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-1.txt"),
- AndroidApiLevel.I.getLevel());
+ AndroidApiLevel.I);
}
@Test
@@ -58,7 +58,7 @@
EXAMPLE_BUILD_DIR,
Paths.get(EXAMPLE_SRC_DIR, "multidex001", "main-dex-rules-2.txt"),
Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-2.txt"),
- AndroidApiLevel.I.getLevel());
+ AndroidApiLevel.I);
}
@Test
@@ -69,7 +69,7 @@
EXAMPLE_BUILD_DIR,
Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
Paths.get(EXAMPLE_SRC_DIR, "multidex002", "ref-list-1.txt"),
- AndroidApiLevel.I.getLevel());
+ AndroidApiLevel.I);
}
@Test
@@ -80,7 +80,7 @@
EXAMPLE_BUILD_DIR,
Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
Paths.get(EXAMPLE_SRC_DIR, "multidex003", "ref-list-1.txt"),
- AndroidApiLevel.I.getLevel());
+ AndroidApiLevel.I);
}
@Test
@@ -91,7 +91,7 @@
EXAMPLE_O_BUILD_DIR,
Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
Paths.get(EXAMPLE_O_SRC_DIR, "multidex004", "ref-list-1.txt"),
- AndroidApiLevel.I.getLevel());
+ AndroidApiLevel.I);
}
@Test
@@ -131,7 +131,7 @@
EXAMPLE_BUILD_DIR,
Paths.get(EXAMPLE_SRC_DIR, "multidex005", "main-dex-rules-" + variant + ".txt"),
Paths.get(EXAMPLE_SRC_DIR, "multidex005", "ref-list-" + variant + ".txt"),
- AndroidApiLevel.I.getLevel());
+ AndroidApiLevel.I);
}
private void doTest(
@@ -140,7 +140,7 @@
String buildDir,
Path mainDexRules,
Path expectedMainDexList,
- int minSdk)
+ AndroidApiLevel minSdk)
throws Throwable {
doTest(
testName,
@@ -160,7 +160,7 @@
String buildDir,
Path mainDexRules,
Path expectedMainDexList,
- int minSdk,
+ AndroidApiLevel minSdk,
Consumer<InternalOptions> optionsConsumer)
throws Throwable {
Path out = temp.getRoot().toPath().resolve(testName + ZIP_EXTENSION);
@@ -170,7 +170,7 @@
// Build main-dex list using GenerateMainDexList and test the output from run.
GenerateMainDexListCommand.Builder mdlCommandBuilder = GenerateMainDexListCommand.builder();
GenerateMainDexListCommand mdlCommand = mdlCommandBuilder
- .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K.getLevel()))
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K))
.addProgramFiles(inputJar)
.addProgramFiles(Paths.get(EXAMPLE_BUILD_DIR, "multidexfakeframeworks" + JAR_EXTENSION))
.addMainDexRulesFiles(mainDexRules)
@@ -189,7 +189,7 @@
final Box mainDexListOutput = new Box();
mdlCommandBuilder = GenerateMainDexListCommand.builder();
mdlCommand = mdlCommandBuilder
- .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K.getLevel()))
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K))
.addProgramFiles(inputJar)
.addProgramFiles(Paths.get(EXAMPLE_BUILD_DIR, "multidexfakeframeworks" + JAR_EXTENSION))
.addMainDexRulesFiles(mainDexRules)
@@ -207,7 +207,7 @@
R8Command.Builder r8CommandBuilder = R8Command.builder();
R8Command command =
r8CommandBuilder
- .setMinApiLevel(minSdk)
+ .setMinApiLevel(minSdk.getLevel())
.addProgramFiles(inputJar)
.addProgramFiles(
Paths.get(EXAMPLE_BUILD_DIR, "multidexfakeframeworks" + JAR_EXTENSION))
diff --git a/src/test/java/com/android/tools/r8/maindexlist/b72312389/B72312389.java b/src/test/java/com/android/tools/r8/maindexlist/b72312389/B72312389.java
index 1d2a942..0f1359e 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/b72312389/B72312389.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/b72312389/B72312389.java
@@ -37,7 +37,7 @@
// and the Android library.
private void buildInstrumentationTestCaseApplication(BaseCommand.Builder builder) {
builder
- .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.O.getLevel()))
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.O))
.addProgramFiles(
Paths.get("build", "test", "examplesAndroidApi",
"classes", "instrumentationtest", "InstrumentationTest.class"))
diff --git a/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java b/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java
index 9dbfb13..490162a 100644
--- a/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java
+++ b/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java
@@ -52,21 +52,39 @@
// Check the instruction used for testInlinedIntoVoidMethod
MethodSubject methodThrowToBeInlined =
- clazz.method("void", "foo", ImmutableList.of("java.lang.String"));
+ clazz.method("void", "foo", ImmutableList.of(
+ "java.lang.String", "java.lang.String", "java.lang.String", "java.lang.String"));
assertTrue(methodThrowToBeInlined.isPresent());
validateSequence(methodThrowToBeInlined.iterateInstructions(),
- InstructionSubject::isIfNez,
+ // 'if' with "foo#1" is flipped.
+ InstructionSubject::isIfEqz,
+
+ // 'if' with "foo#2" is removed along with the constant.
+
+ // 'if' with "foo#3" is removed so now we have unconditional call.
+ insn -> insn.isConstString("StringConstants::foo#3"),
+ InstructionSubject::isInvokeStatic,
+ InstructionSubject::isThrow,
+
+ // 'if's with "foo#4" and "foo#5" are flipped, but their throwing branches
+ // are not moved to the end of the code (area for improvement?).
+ insn -> insn.isConstString("StringConstants::foo#4"),
+ InstructionSubject::isIfEqz, // Flipped if
+ InstructionSubject::isGoto, // Jump around throwing branch.
+ InstructionSubject::isInvokeStatic, // Throwing branch.
+ InstructionSubject::isThrow,
+
+ insn -> insn.isConstString("StringConstants::foo#5"),
+ InstructionSubject::isIfEqz, // Flipped if
+ InstructionSubject::isReturnVoid, // Final return statement.
+ InstructionSubject::isInvokeStatic, // Throwing branch.
+ InstructionSubject::isThrow,
+
+ // After 'if' with "foo#1" flipped, always throwing branch
+ // moved here along with the constant.
insn -> insn.isConstString("StringConstants::foo#1"),
- // Below two are removed by optimization: non-null argument "".
- // InstructionSubject::isIfNez,
- // insn -> insn.isConstString("StringConstants::foo#2"),
- // InstructionSubject::isIfNez, 'removed by optimization'
- insn -> insn.isConstString("StringConstants::foo#3")
- // Below four are removed, since a safe call of arg.length() indicates arg is not null.
- // insn -> insn.isConstString("StringConstants::foo#4"),
- // InstructionSubject::isIfNez,
- // insn -> insn.isConstString("StringConstants::foo#5"),
- // InstructionSubject::isIfNez
+ InstructionSubject::isInvokeStatic,
+ InstructionSubject::isThrow
);
}
diff --git a/src/test/java/com/android/tools/r8/movestringconstants/TestClass.java b/src/test/java/com/android/tools/r8/movestringconstants/TestClass.java
index b801804..bf13fc3 100644
--- a/src/test/java/com/android/tools/r8/movestringconstants/TestClass.java
+++ b/src/test/java/com/android/tools/r8/movestringconstants/TestClass.java
@@ -5,19 +5,19 @@
package com.android.tools.r8.movestringconstants;
public class TestClass {
- static void foo(String arg) {
- Utils.check(arg, "StringConstants::foo#1");
+ static void foo(String arg1, String arg2, String arg3, String arg4) {
+ Utils.check(arg1, "StringConstants::foo#1");
Utils.check("", "StringConstants::foo#2");
- if (arg.length() == 12345) {
+ if (arg2.length() == 12345) {
Utils.check(null, "StringConstants::foo#3");
}
try {
- Utils.check(arg, "StringConstants::foo#4");
+ Utils.check(arg3, "StringConstants::foo#4");
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
- Utils.check(arg, "StringConstants::foo#5");
+ Utils.check(arg4, "StringConstants::foo#5");
} finally {
System.out.println("finally");
}
diff --git a/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java b/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java
index 84dd3b7..ca86a53 100644
--- a/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java
+++ b/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.debug.DebugTestBase;
import com.android.tools.r8.debug.DebugTestConfig;
import com.android.tools.r8.debug.DexDebugTestConfig;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import org.junit.BeforeClass;
@@ -26,7 +27,7 @@
@BeforeClass
public static void initDebuggeePath() throws Exception {
- int minSdk = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm());
+ AndroidApiLevel minSdk = ToolHelper.getMinApiLevelForDexVm();
Path outdir = temp.newFolder().toPath();
Path outjar = outdir.resolve("r8_compiled.jar");
Path proguardMapPath = outdir.resolve("proguard.map");
@@ -39,7 +40,7 @@
ImmutableList.of("SourceFile", "LineNumberTable"));
})
.addProgramFiles(DEBUGGEE_JAR)
- .setMinApiLevel(minSdk)
+ .setMinApiLevel(minSdk.getLevel())
.addLibraryFiles(ToolHelper.getAndroidJar(minSdk))
.setMode(CompilationMode.DEBUG)
.setOutput(outjar, OutputMode.DexIndexed)
diff --git a/src/test/java/com/android/tools/r8/naming/overloadaggressively/A.java b/src/test/java/com/android/tools/r8/naming/overloadaggressively/A.java
index af4c4b2..96b8a06 100644
--- a/src/test/java/com/android/tools/r8/naming/overloadaggressively/A.java
+++ b/src/test/java/com/android/tools/r8/naming/overloadaggressively/A.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.naming.overloadaggressively;
public class A {
- volatile int f1;
+ public volatile int f1;
volatile Object f2;
- volatile B f3;
+ public volatile B f3;
}
diff --git a/src/test/java/com/android/tools/r8/naming/overloadaggressively/B.java b/src/test/java/com/android/tools/r8/naming/overloadaggressively/B.java
index 78f5a24..6660196 100644
--- a/src/test/java/com/android/tools/r8/naming/overloadaggressively/B.java
+++ b/src/test/java/com/android/tools/r8/naming/overloadaggressively/B.java
@@ -4,6 +4,19 @@
package com.android.tools.r8.naming.overloadaggressively;
public class B {
- volatile int f1;
- volatile Object f2;
+ volatile int f1 = 8;
+ volatile Object f2 = "d8";
+ volatile String f3 = "r8";
+
+ public int getF1() {
+ return f1;
+ }
+
+ public Object getF2() {
+ return f2;
+ }
+
+ public String getF3() {
+ return f3;
+ }
}
diff --git a/src/test/java/com/android/tools/r8/naming/overloadaggressively/FieldResolution.java b/src/test/java/com/android/tools/r8/naming/overloadaggressively/FieldResolution.java
new file mode 100644
index 0000000..26f5df6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/overloadaggressively/FieldResolution.java
@@ -0,0 +1,27 @@
+// 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.naming.overloadaggressively;
+
+import java.lang.reflect.Field;
+import java.util.Random;
+
+public class FieldResolution {
+ public static void main(String[] args) throws Exception {
+ A a = new A();
+ B b = new B();
+
+ Field f3 = A.class.getField("f3");
+ f3.set(a, b);
+ assert a.f3 != null;
+ assert a.f3 == b;
+
+ Field f1 = A.class.getField("f1");
+ Random random = new Random();
+ int next = random.nextInt();
+ f1.set(a, next);
+ a.f3.f1 = next;
+ int diff = a.f1 - b.f1;
+ System.out.println("diff: " + diff);
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/naming/overloadaggressively/Main.java b/src/test/java/com/android/tools/r8/naming/overloadaggressively/FieldUpdater.java
similarity index 97%
rename from src/test/java/com/android/tools/r8/naming/overloadaggressively/Main.java
rename to src/test/java/com/android/tools/r8/naming/overloadaggressively/FieldUpdater.java
index 956b198..8f5011c 100644
--- a/src/test/java/com/android/tools/r8/naming/overloadaggressively/Main.java
+++ b/src/test/java/com/android/tools/r8/naming/overloadaggressively/FieldUpdater.java
@@ -7,7 +7,7 @@
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-public class Main {
+public class FieldUpdater {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception {
A a = new A();
diff --git a/src/test/java/com/android/tools/r8/naming/overloadaggressively/MethodResolution.java b/src/test/java/com/android/tools/r8/naming/overloadaggressively/MethodResolution.java
new file mode 100644
index 0000000..c791031
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/overloadaggressively/MethodResolution.java
@@ -0,0 +1,25 @@
+// 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.naming.overloadaggressively;
+
+import java.lang.reflect.Method;
+
+public class MethodResolution {
+ public static void main(String[] args) throws Exception {
+ B b = new B();
+
+ int originalF1 = b.getF1();
+ Method getF1 = B.class.getMethod("getF1", (Class[]) null);
+ int diff = ((Integer) getF1.invoke(b)) - originalF1;
+ System.out.println("diff: " + diff);
+
+ Object originalF2 = b.getF2();
+ Method getF2 = B.class.getMethod("getF2", (Class[]) null);
+ System.out.println(originalF2 + " v.s. " + getF2.invoke(b));
+
+ String originalF3 = b.getF3();
+ Method getF3 = B.class.getMethod("getF3", (Class[]) null);
+ System.out.println(originalF3 + " v.s. " + getF3.invoke(b));
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/naming/overloadaggressively/OverloadAggressivelyTest.java b/src/test/java/com/android/tools/r8/naming/overloadaggressively/OverloadAggressivelyTest.java
index d0cdb28..1254d4b 100644
--- a/src/test/java/com/android/tools/r8/naming/overloadaggressively/OverloadAggressivelyTest.java
+++ b/src/test/java/com/android/tools/r8/naming/overloadaggressively/OverloadAggressivelyTest.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.ToolHelper.DexVm.Kind;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DexInspector;
@@ -55,54 +56,144 @@
return testCases;
}
- @Test
- public void overloadAggressivelyTest() throws Exception {
- Assume.assumeTrue(ToolHelper.artSupported());
- byte[][] classes = {
- ToolHelper.getClassAsBytes(Main.class),
- ToolHelper.getClassAsBytes(A.class),
- ToolHelper.getClassAsBytes(B.class)
- };
- AndroidApp originalApp = buildAndroidApp(classes);
- Path out = temp.getRoot().toPath();
- R8Command command =
+ private AndroidApp runR8(AndroidApp app, Class main, Path out) throws Exception {
+ R8Command command =
ToolHelper.addProguardConfigurationConsumer(
- ToolHelper.prepareR8CommandBuilder(originalApp),
+ ToolHelper.prepareR8CommandBuilder(app),
pgConfig -> {
pgConfig.setPrintMapping(true);
pgConfig.setPrintMappingFile(out.resolve(ToolHelper.DEFAULT_PROGUARD_MAP_FILE));
})
.addProguardConfiguration(
ImmutableList.copyOf(Iterables.concat(ImmutableList.of(
- keepMainProguardConfiguration(Main.class),
+ keepMainProguardConfiguration(main),
overloadaggressively ? "-overloadaggressively" : ""),
CompatProguardCommandBuilder.REFLECTIONS)),
Origin.unknown())
.setOutput(out, OutputMode.DexIndexed)
.build();
- AndroidApp processedApp = ToolHelper.runR8(command);
+ return ToolHelper.runR8(command, o -> o.inlineAccessors = false);
+ }
- DexInspector dexInspector = new DexInspector(
- out.resolve(ToolHelper.DEFAULT_DEX_FILENAME),
- out.resolve(ToolHelper.DEFAULT_PROGUARD_MAP_FILE).toString());
+ @Test
+ public void fieldUpdater() throws Exception {
+ Assume.assumeTrue(ToolHelper.artSupported());
+ byte[][] classes = {
+ ToolHelper.getClassAsBytes(FieldUpdater.class),
+ ToolHelper.getClassAsBytes(A.class),
+ ToolHelper.getClassAsBytes(B.class)
+ };
+ AndroidApp originalApp = buildAndroidApp(classes);
+ Path out = temp.getRoot().toPath();
+ AndroidApp processedApp = runR8(originalApp, FieldUpdater.class, out);
+
+ DexInspector dexInspector = new DexInspector(processedApp);
ClassSubject a = dexInspector.clazz(A.class.getCanonicalName());
DexEncodedField f1 = a.field("int", "f1").getField();
assertNotNull(f1);
DexEncodedField f2 = a.field("java.lang.Object", "f2").getField();
assertNotNull(f2);
+ // TODO(b/72858955): due to the potential reflective access, they should have different names
+ // by R8's improved reflective access detection or via keep rules.
assertEquals(overloadaggressively, f1.field.name == f2.field.name);
DexEncodedField f3 = a.field(B.class.getCanonicalName(), "f3").getField();
assertNotNull(f3);
+ // TODO(b/72858955): ditto
assertEquals(overloadaggressively, f1.field.name == f3.field.name);
+ // TODO(b/72858955): ditto
assertEquals(overloadaggressively, f2.field.name == f3.field.name);
- ProcessResult javaOutput = runOnJava(Main.class.getCanonicalName(), classes);
- ProcessResult artOutput = runOnArtRaw(processedApp, Main.class.getCanonicalName(), dexVm);
+ String main = FieldUpdater.class.getCanonicalName();
+ ProcessResult javaOutput = runOnJava(main, classes);
+ assertEquals(0, javaOutput.exitCode);
+ ProcessResult artOutput = runOnArtRaw(processedApp, main, dexVm);
+ // TODO(b/72858955): eventually, R8 should avoid this field resolution conflict.
if (overloadaggressively) {
assertNotEquals(0, artOutput.exitCode);
assertTrue(artOutput.stderr.contains("ClassCastException"));
} else {
- assertEquals(0, javaOutput.exitCode);
+ assertEquals(0, artOutput.exitCode);
+ assertEquals(javaOutput.stdout.trim(), artOutput.stdout.trim());
+ // ART may dump its own debugging info through stderr.
+ // assertEquals(javaOutput.stderr.trim(), artOutput.stderr.trim());
+ }
+ }
+
+ @Test
+ public void fieldResolution() throws Exception {
+ Assume.assumeTrue(ToolHelper.artSupported());
+ byte[][] classes = {
+ ToolHelper.getClassAsBytes(FieldResolution.class),
+ ToolHelper.getClassAsBytes(A.class),
+ ToolHelper.getClassAsBytes(B.class)
+ };
+ AndroidApp originalApp = buildAndroidApp(classes);
+ Path out = temp.getRoot().toPath();
+ AndroidApp processedApp = runR8(originalApp, FieldResolution.class, out);
+
+ DexInspector dexInspector = new DexInspector(processedApp);
+ ClassSubject a = dexInspector.clazz(A.class.getCanonicalName());
+ DexEncodedField f1 = a.field("int", "f1").getField();
+ assertNotNull(f1);
+ DexEncodedField f3 = a.field(B.class.getCanonicalName(), "f3").getField();
+ assertNotNull(f3);
+ // TODO(b/72858955): due to the potential reflective access, they should have different names
+ // by R8's improved reflective access detection or via keep rules.
+ assertEquals(overloadaggressively, f1.field.name == f3.field.name);
+
+ String main = FieldResolution.class.getCanonicalName();
+ ProcessResult javaOutput = runOnJava(main, classes);
+ assertEquals(0, javaOutput.exitCode);
+ ProcessResult artOutput = runOnArtRaw(processedApp, main, dexVm);
+ // TODO(b/72858955): R8 should avoid field resolution conflict even w/ -overloadaggressively.
+ if (overloadaggressively) {
+ assertNotEquals(0, artOutput.exitCode);
+ assertTrue(artOutput.stderr.contains("IllegalArgumentException"));
+ } else {
+ assertEquals(0, artOutput.exitCode);
+ assertEquals(javaOutput.stdout.trim(), artOutput.stdout.trim());
+ // ART may dump its own debugging info through stderr.
+ // assertEquals(javaOutput.stderr.trim(), artOutput.stderr.trim());
+ }
+ }
+
+ @Test
+ public void methodResolution() throws Exception {
+ Assume.assumeTrue(ToolHelper.artSupported());
+ byte[][] classes = {
+ ToolHelper.getClassAsBytes(MethodResolution.class),
+ ToolHelper.getClassAsBytes(B.class)
+ };
+ AndroidApp originalApp = buildAndroidApp(classes);
+ Path out = temp.getRoot().toPath();
+ AndroidApp processedApp = runR8(originalApp, MethodResolution.class, out);
+
+ DexInspector dexInspector = new DexInspector(processedApp);
+ ClassSubject b = dexInspector.clazz(B.class.getCanonicalName());
+ DexEncodedMethod m1 =
+ b.method("int", "getF1", ImmutableList.of()).getMethod();
+ assertNotNull(m1);
+ DexEncodedMethod m2 =
+ b.method("java.lang.Object", "getF2", ImmutableList.of()).getMethod();
+ // TODO(b/72858955): due to the potential reflective access, they should have different names.
+ assertEquals(overloadaggressively, m1.method.name == m2.method.name);
+ DexEncodedMethod m3 =
+ b.method("java.lang.String", "getF3", ImmutableList.of()).getMethod();
+ assertNotNull(m3);
+ // TODO(b/72858955): ditto
+ assertEquals(overloadaggressively, m1.method.name == m3.method.name);
+ // TODO(b/72858955): ditto
+ assertEquals(overloadaggressively, m2.method.name == m3.method.name);
+
+ String main = MethodResolution.class.getCanonicalName();
+ ProcessResult javaOutput = runOnJava(main, classes);
+ assertEquals(0, javaOutput.exitCode);
+ ProcessResult artOutput = runOnArtRaw(processedApp, main, dexVm);
+ // TODO(b/72858955): R8 should avoid method resolution conflict even w/ -overloadaggressively.
+ if (overloadaggressively) {
+ assertEquals(0, artOutput.exitCode);
+ assertNotEquals(javaOutput.stdout.trim(), artOutput.stdout.trim());
+ } else {
assertEquals(0, artOutput.exitCode);
assertEquals(javaOutput.stdout.trim(), artOutput.stdout.trim());
// ART may dump its own debugging info through stderr.
diff --git a/src/test/java/com/android/tools/r8/regress/b69906048/Regress69906048Test.java b/src/test/java/com/android/tools/r8/regress/b69906048/Regress69906048Test.java
index 0553fe4..f1d846e 100644
--- a/src/test/java/com/android/tools/r8/regress/b69906048/Regress69906048Test.java
+++ b/src/test/java/com/android/tools/r8/regress/b69906048/Regress69906048Test.java
@@ -16,7 +16,7 @@
public void buildWithD8AndRunWithDalvikOrArt() throws Exception {
AndroidApp androidApp = compileWithR8(
ImmutableList.of(ClassWithAnnotations.class, AnAnnotation.class),
- options -> options.minApiLevel = ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm()));
+ options -> options.minApiLevel = ToolHelper.getMinApiLevelForDexVm().getLevel());
String result = runOnArt(androidApp, ClassWithAnnotations.class);
Assert.assertEquals("@" + AnAnnotation.class.getCanonicalName() + "()", result);
}
diff --git a/src/test/java/com/android/tools/r8/resolution/SingleTargetExecutionTest.java b/src/test/java/com/android/tools/r8/resolution/SingleTargetExecutionTest.java
index 0584aa0..cf2be59 100644
--- a/src/test/java/com/android/tools/r8/resolution/SingleTargetExecutionTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/SingleTargetExecutionTest.java
@@ -49,7 +49,7 @@
allBytes.add(ToolHelper.getClassAsBytes(clazz));
}
ensureSameOutput(Main.class.getCanonicalName(),
- ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm()),
+ ToolHelper.getMinApiLevelForDexVm(),
allBytes.toArray(new byte[allBytes.size()][]));
}
}
diff --git a/src/test/java/com/android/tools/r8/utils/DexInspector.java b/src/test/java/com/android/tools/r8/utils/DexInspector.java
index f087d0d..95ecd4f 100644
--- a/src/test/java/com/android/tools/r8/utils/DexInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/DexInspector.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.code.Const4;
import com.android.tools.r8.code.ConstString;
import com.android.tools.r8.code.Goto;
+import com.android.tools.r8.code.IfEqz;
import com.android.tools.r8.code.IfNez;
import com.android.tools.r8.code.Iget;
import com.android.tools.r8.code.IgetBoolean;
@@ -1001,6 +1002,10 @@
return instruction instanceof IfNez;
}
+ boolean isIfEqz(Instruction instruction) {
+ return instruction instanceof IfEqz;
+ }
+
boolean isFieldAccess(Instruction instruction) {
return isInstanceGet(instruction)
|| isInstancePut(instruction)
@@ -1111,6 +1116,10 @@
return factory.isIfNez(instruction);
}
+ public boolean isIfEqz() {
+ return factory.isIfEqz(instruction);
+ }
+
public boolean isReturnVoid() {
return factory.isReturnVoid(instruction);
}
diff --git a/src/test/java/com/android/tools/r8/utils/GenerateMainDexListCommandTest.java b/src/test/java/com/android/tools/r8/utils/GenerateMainDexListCommandTest.java
index b14ef8a..fb4fe70 100644
--- a/src/test/java/com/android/tools/r8/utils/GenerateMainDexListCommandTest.java
+++ b/src/test/java/com/android/tools/r8/utils/GenerateMainDexListCommandTest.java
@@ -61,7 +61,7 @@
private void addAndroidJarsToCommandLine(List<String> args) {
args.add("--lib");
- args.add(ToolHelper.getAndroidJar(AndroidApiLevel.K.getLevel()).toAbsolutePath().toString());
+ args.add(ToolHelper.getAndroidJar(AndroidApiLevel.K).toAbsolutePath().toString());
}
// Add the jars used in the com.android.tools.r8.maindexlist.MainDexTracingTest test.
diff --git a/src/test/kotlinR8TestResources/dataclass/MainCopy.kt b/src/test/kotlinR8TestResources/dataclass/MainCopy.kt
index 2e4f047..2644302 100644
--- a/src/test/kotlinR8TestResources/dataclass/MainCopy.kt
+++ b/src/test/kotlinR8TestResources/dataclass/MainCopy.kt
@@ -16,7 +16,8 @@
fun testDataClassCopy() {
val albert = Person("Albert", 28)
- val olderJonas = albert.copy("Jonas", albert.age + 10)
+ val youngerJonas = albert.copy("Jonas", albert.age - 10)
+ val olderJonas = youngerJonas.copy("Jonas", albert.age + 20)
println("Name: ${olderJonas.name}")
println("Age: ${olderJonas.age}")
}
\ No newline at end of file
diff --git a/src/test/kotlinR8TestResources/dataclass/MainCopyWithDefault.kt b/src/test/kotlinR8TestResources/dataclass/MainCopyWithDefault.kt
deleted file mode 100644
index 2df19f7..0000000
--- a/src/test/kotlinR8TestResources/dataclass/MainCopyWithDefault.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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 dataclass
-
-/**
- * This is an example of copying an instance of a data class Person using its copy method and
- * relying on default values for some of its properties. Therefore the compiler will generate an
- * invoke to copy$default method which is a wrapper around copy and deals with default values.
- *
- * See https://kotlinlang.org/docs/reference/data-classes.html#copying.
- */
-fun main(args: Array<String>) {
- testDataClassCopyWithDefault()
-}
-
-fun testDataClassCopyWithDefault() {
- val albert = Person("Albert", 28)
- // We don't pass a 'name', thus we copy the property value of the receiver. This will result
- // in calling the copy$default method instead of the copy method.
- val olderAlbert = albert.copy(age = albert.age + 10)
- println("Name: ${olderAlbert.name}")
- println("Age: ${olderAlbert.age}")
-}
\ No newline at end of file
diff --git a/tools/archive.py b/tools/archive.py
index 360a0ee..815e416 100755
--- a/tools/archive.py
+++ b/tools/archive.py
@@ -113,6 +113,14 @@
print('Uploading %s to %s' % (tagged_jar, destination))
utils.upload_file_to_cloud_storage(tagged_jar, destination)
print('File available at: %s' % GetUrl(version, file_name, is_master))
+ # Upload extracted maven directory for easy testing in studio.
+ zip_ref = zipfile.ZipFile(utils.MAVEN_ZIP, 'r')
+ zip_ref.extractall(temp)
+ zip_ref.close()
+ utils.upload_dir_to_cloud_storage(
+ os.path.join(temp, 'com'),
+ GetUploadDestination(version, 'com', is_master))
+ print('Maven repo root available at: %s' % GetUrl(version, '', is_master))
if __name__ == '__main__':
sys.exit(Main())
diff --git a/tools/test.py b/tools/test.py
index 58fc4eb..ed99c1d 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -85,7 +85,7 @@
upload_dir = os.path.join(utils.REPO_ROOT, 'build', 'reports', 'tests')
u_dir = uuid.uuid4()
destination = 'gs://%s/%s' % (BUCKET, u_dir)
- utils.upload_dir_to_cloud_storage(upload_dir, destination)
+ utils.upload_dir_to_cloud_storage(upload_dir, destination, is_html=True)
url = 'http://storage.googleapis.com/%s/%s/test/index.html' % (BUCKET, u_dir)
print 'Test results available at: %s' % url
print '@@@STEP_LINK@Test failures@%s@@@' % url
@@ -166,4 +166,3 @@
else:
notify.notify("Tests passed.")
sys.exit(return_code)
-
diff --git a/tools/utils.py b/tools/utils.py
index 47acca5..8716f65 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -73,10 +73,12 @@
if not os.path.isdir(path):
raise
-def upload_dir_to_cloud_storage(directory, destination):
+def upload_dir_to_cloud_storage(directory, destination, is_html=False):
# Upload and make the content encoding right for viewing directly
- cmd = ['gsutil.py', 'cp', '-z', 'html', '-a',
- 'public-read', '-R', directory, destination]
+ cmd = ['gsutil.py', 'cp']
+ if is_html:
+ cmd += ['-z', 'html']
+ cmd += ['-a', 'public-read', '-R', directory, destination]
PrintCmd(cmd)
subprocess.check_call(cmd)