Include hierarchy of direct dependencies
Direct dependency classes may be loaded before secondary dex
installation: so their hierarchy is needed in the main dex or they
will be rejected at load and cause NoClassDefFoundError at first use.
Bug: 72039872
Change-Id: Ida42c70f9c8e1c7e16ad779bce7ea038a8124782
diff --git a/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java b/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java
index 97af687..f8b54ab 100644
--- a/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/MainDexListBuilder.java
@@ -163,11 +163,37 @@
private void traceMethodDirectDependencies(DexMethod method) {
DexProto proto = method.proto;
addMainDexType(proto.returnType);
- Collections.addAll(mainDexTypes, proto.parameters.values);
+ for (DexType parameterType : proto.parameters.values) {
+ addMainDexType(parameterType);
+ }
}
private void addMainDexType(DexType type) {
- mainDexTypes.add(type);
+ // Consider only component type of arrays
+ type = type.toBaseType(appInfo.dexItemFactory);
+
+ if (!type.isClassType()) {
+ return;
+ }
+
+ DexClass clazz = appInfo.definitionFor(type);
+ if (clazz == null) {
+ // Happens for library classes.
+ return;
+ }
+ addMainDexType(clazz);
+ }
+
+ private void addMainDexType(DexClass dexClass) {
+ DexType type = dexClass.type;
+ if (mainDexTypes.add(type)) {
+ if (dexClass.superType != null) {
+ addMainDexType(dexClass.superType);
+ }
+ for (DexType interfaze : dexClass.interfaces.values) {
+ addMainDexType(interfaze);
+ }
+ }
}
private class DirectReferencesCollector extends UseRegistry {
diff --git a/src/test/examples/multidex005/ClassReference.java b/src/test/examples/multidex005/ClassReference.java
new file mode 100644
index 0000000..b92af78
--- /dev/null
+++ b/src/test/examples/multidex005/ClassReference.java
@@ -0,0 +1,12 @@
+// 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 multidex005;
+
+public class ClassReference {
+
+ public Object directReference() {
+ return DirectlyReferenced.class;
+ }
+}
diff --git a/src/test/examples/multidex005/DirectlyReferenced.java b/src/test/examples/multidex005/DirectlyReferenced.java
new file mode 100644
index 0000000..d759e77
--- /dev/null
+++ b/src/test/examples/multidex005/DirectlyReferenced.java
@@ -0,0 +1,16 @@
+// 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 multidex005;
+
+public class DirectlyReferenced extends SuperClass implements Interface1, Interface2 {
+
+ private IndirectlyReferenced reference = new IndirectlyReferenced();
+
+ public static Object field = null;
+
+ public static Object get() {
+ return null;
+ }
+}
diff --git a/src/test/examples/multidex005/FieldReference.java b/src/test/examples/multidex005/FieldReference.java
new file mode 100644
index 0000000..21b3995b
--- /dev/null
+++ b/src/test/examples/multidex005/FieldReference.java
@@ -0,0 +1,10 @@
+// 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 multidex005;
+
+public class FieldReference {
+
+ private static DirectlyReferenced directReference = null;
+}
diff --git a/src/test/examples/multidex005/GetFieldReference.java b/src/test/examples/multidex005/GetFieldReference.java
new file mode 100644
index 0000000..e195fd7
--- /dev/null
+++ b/src/test/examples/multidex005/GetFieldReference.java
@@ -0,0 +1,12 @@
+// 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 multidex005;
+
+public class GetFieldReference {
+
+ public Object directReference() {
+ return DirectlyReferenced.field;
+ }
+}
diff --git a/src/test/examples/multidex005/IndirectlyReferenced.java b/src/test/examples/multidex005/IndirectlyReferenced.java
new file mode 100644
index 0000000..15c9a2c
--- /dev/null
+++ b/src/test/examples/multidex005/IndirectlyReferenced.java
@@ -0,0 +1,9 @@
+// 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 multidex005;
+
+public class IndirectlyReferenced extends IndirectlyReferencedSuperClass
+ implements IndirectlyReferencedInterface {
+}
diff --git a/src/test/examples/multidex005/IndirectlyReferencedInterface.java b/src/test/examples/multidex005/IndirectlyReferencedInterface.java
new file mode 100644
index 0000000..ea728ca
--- /dev/null
+++ b/src/test/examples/multidex005/IndirectlyReferencedInterface.java
@@ -0,0 +1,8 @@
+// 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 multidex005;
+
+public interface IndirectlyReferencedInterface {
+}
diff --git a/src/test/examples/multidex005/IndirectlyReferencedSuperClass.java b/src/test/examples/multidex005/IndirectlyReferencedSuperClass.java
new file mode 100644
index 0000000..6641273
--- /dev/null
+++ b/src/test/examples/multidex005/IndirectlyReferencedSuperClass.java
@@ -0,0 +1,9 @@
+// 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 multidex005;
+
+public class IndirectlyReferencedSuperClass implements IndirectlyReferencedInterface {
+
+}
diff --git a/src/test/examples/multidex005/Interface1.java b/src/test/examples/multidex005/Interface1.java
new file mode 100644
index 0000000..afd040b
--- /dev/null
+++ b/src/test/examples/multidex005/Interface1.java
@@ -0,0 +1,8 @@
+// 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 multidex005;
+
+public interface Interface1 {
+}
diff --git a/src/test/examples/multidex005/Interface2.java b/src/test/examples/multidex005/Interface2.java
new file mode 100644
index 0000000..5d4ac94
--- /dev/null
+++ b/src/test/examples/multidex005/Interface2.java
@@ -0,0 +1,8 @@
+// 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 multidex005;
+
+public interface Interface2 extends SuperInterface {
+}
diff --git a/src/test/examples/multidex005/Interface3.java b/src/test/examples/multidex005/Interface3.java
new file mode 100644
index 0000000..ea3fc72
--- /dev/null
+++ b/src/test/examples/multidex005/Interface3.java
@@ -0,0 +1,9 @@
+// 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 multidex005;
+
+public interface Interface3 {
+
+}
diff --git a/src/test/examples/multidex005/InvokeReference.java b/src/test/examples/multidex005/InvokeReference.java
new file mode 100644
index 0000000..5cdf795
--- /dev/null
+++ b/src/test/examples/multidex005/InvokeReference.java
@@ -0,0 +1,12 @@
+// 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 multidex005;
+
+public class InvokeReference {
+
+ public Object directReference() {
+ return DirectlyReferenced.get();
+ }
+}
diff --git a/src/test/examples/multidex005/NewReference.java b/src/test/examples/multidex005/NewReference.java
new file mode 100644
index 0000000..27ce713
--- /dev/null
+++ b/src/test/examples/multidex005/NewReference.java
@@ -0,0 +1,12 @@
+// 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 multidex005;
+
+public class NewReference {
+
+ public Object directReference() {
+ return new DirectlyReferenced();
+ }
+}
diff --git a/src/test/examples/multidex005/ParameterReference.java b/src/test/examples/multidex005/ParameterReference.java
new file mode 100644
index 0000000..000715d
--- /dev/null
+++ b/src/test/examples/multidex005/ParameterReference.java
@@ -0,0 +1,11 @@
+// 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 multidex005;
+
+public class ParameterReference {
+
+ public void directReference(Object o, DirectlyReferenced ref) {
+ }
+}
diff --git a/src/test/examples/multidex005/ReturnReference.java b/src/test/examples/multidex005/ReturnReference.java
new file mode 100644
index 0000000..ef9a4e0
--- /dev/null
+++ b/src/test/examples/multidex005/ReturnReference.java
@@ -0,0 +1,12 @@
+// 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 multidex005;
+
+public class ReturnReference {
+
+ public DirectlyReferenced directReference() {
+ return null;
+ }
+}
diff --git a/src/test/examples/multidex005/SuperClass.java b/src/test/examples/multidex005/SuperClass.java
new file mode 100644
index 0000000..74c8986
--- /dev/null
+++ b/src/test/examples/multidex005/SuperClass.java
@@ -0,0 +1,8 @@
+// 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 multidex005;
+
+public class SuperClass extends SuperSuperClass {
+}
diff --git a/src/test/examples/multidex005/SuperInterface.java b/src/test/examples/multidex005/SuperInterface.java
new file mode 100644
index 0000000..a0d811f
--- /dev/null
+++ b/src/test/examples/multidex005/SuperInterface.java
@@ -0,0 +1,8 @@
+// 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 multidex005;
+
+public interface SuperInterface {
+}
diff --git a/src/test/examples/multidex005/SuperSuperClass.java b/src/test/examples/multidex005/SuperSuperClass.java
new file mode 100644
index 0000000..caed119
--- /dev/null
+++ b/src/test/examples/multidex005/SuperSuperClass.java
@@ -0,0 +1,8 @@
+// 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 multidex005;
+
+public class SuperSuperClass implements Interface3 {
+}
diff --git a/src/test/examples/multidex005/main-dex-rules-1.txt b/src/test/examples/multidex005/main-dex-rules-1.txt
new file mode 100644
index 0000000..d5fc8d1
--- /dev/null
+++ b/src/test/examples/multidex005/main-dex-rules-1.txt
@@ -0,0 +1,7 @@
+# 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.
+
+-keep public class *.NewReference {
+ <init>();
+}
diff --git a/src/test/examples/multidex005/main-dex-rules-2.txt b/src/test/examples/multidex005/main-dex-rules-2.txt
new file mode 100644
index 0000000..9e16c8c
--- /dev/null
+++ b/src/test/examples/multidex005/main-dex-rules-2.txt
@@ -0,0 +1,7 @@
+# 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.
+
+-keep public class *.ParameterReference {
+ <init>();
+}
diff --git a/src/test/examples/multidex005/main-dex-rules-3.txt b/src/test/examples/multidex005/main-dex-rules-3.txt
new file mode 100644
index 0000000..72efbce
--- /dev/null
+++ b/src/test/examples/multidex005/main-dex-rules-3.txt
@@ -0,0 +1,7 @@
+# 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.
+
+-keep public class *.ReturnReference {
+ <init>();
+}
diff --git a/src/test/examples/multidex005/main-dex-rules-4.txt b/src/test/examples/multidex005/main-dex-rules-4.txt
new file mode 100644
index 0000000..75f6606
--- /dev/null
+++ b/src/test/examples/multidex005/main-dex-rules-4.txt
@@ -0,0 +1,7 @@
+# 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.
+
+-keep public class *.FieldReference {
+ <init>();
+}
diff --git a/src/test/examples/multidex005/main-dex-rules-5.txt b/src/test/examples/multidex005/main-dex-rules-5.txt
new file mode 100644
index 0000000..85ec308
--- /dev/null
+++ b/src/test/examples/multidex005/main-dex-rules-5.txt
@@ -0,0 +1,7 @@
+# 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.
+
+-keep public class *.GetFieldReference {
+ <init>();
+}
diff --git a/src/test/examples/multidex005/main-dex-rules-6.txt b/src/test/examples/multidex005/main-dex-rules-6.txt
new file mode 100644
index 0000000..c58aaa1
--- /dev/null
+++ b/src/test/examples/multidex005/main-dex-rules-6.txt
@@ -0,0 +1,7 @@
+# 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.
+
+-keep public class *.ClassReference {
+ <init>();
+}
diff --git a/src/test/examples/multidex005/ref-list-1.txt b/src/test/examples/multidex005/ref-list-1.txt
new file mode 100644
index 0000000..f39cd02
--- /dev/null
+++ b/src/test/examples/multidex005/ref-list-1.txt
@@ -0,0 +1,8 @@
+Lmultidex005/DirectlyReferenced;
+Lmultidex005/Interface1;
+Lmultidex005/Interface2;
+Lmultidex005/Interface3;
+Lmultidex005/NewReference;
+Lmultidex005/SuperClass;
+Lmultidex005/SuperInterface;
+Lmultidex005/SuperSuperClass;
\ No newline at end of file
diff --git a/src/test/examples/multidex005/ref-list-2.txt b/src/test/examples/multidex005/ref-list-2.txt
new file mode 100644
index 0000000..d9747fd
--- /dev/null
+++ b/src/test/examples/multidex005/ref-list-2.txt
@@ -0,0 +1,8 @@
+Lmultidex005/DirectlyReferenced;
+Lmultidex005/Interface1;
+Lmultidex005/Interface2;
+Lmultidex005/Interface3;
+Lmultidex005/ParameterReference;
+Lmultidex005/SuperClass;
+Lmultidex005/SuperInterface;
+Lmultidex005/SuperSuperClass;
\ No newline at end of file
diff --git a/src/test/examples/multidex005/ref-list-3.txt b/src/test/examples/multidex005/ref-list-3.txt
new file mode 100644
index 0000000..77c3082
--- /dev/null
+++ b/src/test/examples/multidex005/ref-list-3.txt
@@ -0,0 +1,8 @@
+Lmultidex005/DirectlyReferenced;
+Lmultidex005/Interface1;
+Lmultidex005/Interface2;
+Lmultidex005/Interface3;
+Lmultidex005/ReturnReference;
+Lmultidex005/SuperClass;
+Lmultidex005/SuperInterface;
+Lmultidex005/SuperSuperClass;
\ No newline at end of file
diff --git a/src/test/examples/multidex005/ref-list-4.txt b/src/test/examples/multidex005/ref-list-4.txt
new file mode 100644
index 0000000..ea7b0f7
--- /dev/null
+++ b/src/test/examples/multidex005/ref-list-4.txt
@@ -0,0 +1,8 @@
+Lmultidex005/DirectlyReferenced;
+Lmultidex005/FieldReference;
+Lmultidex005/Interface1;
+Lmultidex005/Interface2;
+Lmultidex005/Interface3;
+Lmultidex005/SuperClass;
+Lmultidex005/SuperInterface;
+Lmultidex005/SuperSuperClass;
\ No newline at end of file
diff --git a/src/test/examples/multidex005/ref-list-5.txt b/src/test/examples/multidex005/ref-list-5.txt
new file mode 100644
index 0000000..9ef31f8
--- /dev/null
+++ b/src/test/examples/multidex005/ref-list-5.txt
@@ -0,0 +1,8 @@
+Lmultidex005/DirectlyReferenced;
+Lmultidex005/GetFieldReference;
+Lmultidex005/Interface1;
+Lmultidex005/Interface2;
+Lmultidex005/Interface3;
+Lmultidex005/SuperClass;
+Lmultidex005/SuperInterface;
+Lmultidex005/SuperSuperClass;
\ No newline at end of file
diff --git a/src/test/examples/multidex005/ref-list-6.txt b/src/test/examples/multidex005/ref-list-6.txt
new file mode 100644
index 0000000..8351a7f
--- /dev/null
+++ b/src/test/examples/multidex005/ref-list-6.txt
@@ -0,0 +1,8 @@
+Lmultidex005/ClassReference;
+Lmultidex005/DirectlyReferenced;
+Lmultidex005/Interface1;
+Lmultidex005/Interface2;
+Lmultidex005/Interface3;
+Lmultidex005/SuperClass;
+Lmultidex005/SuperInterface;
+Lmultidex005/SuperSuperClass;
\ No newline at end of file
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 c1ca27b..8b143da 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
@@ -94,6 +94,46 @@
AndroidApiLevel.I.getLevel());
}
+ @Test
+ public void traceMainDexList005_1() throws Throwable {
+ doTest5(1);
+ }
+
+ @Test
+ public void traceMainDexList005_2() throws Throwable {
+ doTest5(2);
+ }
+
+ @Test
+ public void traceMainDexList005_3() throws Throwable {
+ doTest5(3);
+ }
+
+ @Test
+ public void traceMainDexList005_4() throws Throwable {
+ doTest5(4);
+ }
+
+ @Test
+ public void traceMainDexList005_5() throws Throwable {
+ doTest5(5);
+ }
+
+ @Test
+ public void traceMainDexList005_6() throws Throwable {
+ doTest5(6);
+ }
+
+ private void doTest5(int variant) throws Throwable {
+ doTest(
+ "traceMainDexList003",
+ "multidex005",
+ 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());
+ }
+
private void doTest(
String testName,
String packageName,