Implement simple class merger.
BUG=
Change-Id: Ib22cf7a7d10797b0ba7ed6ef8fb5aa5fda9aaa60
diff --git a/src/test/examples/classmerging/ClassWithConflictingMethod.java b/src/test/examples/classmerging/ClassWithConflictingMethod.java
new file mode 100644
index 0000000..b4bf9d7
--- /dev/null
+++ b/src/test/examples/classmerging/ClassWithConflictingMethod.java
@@ -0,0 +1,11 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public class ClassWithConflictingMethod {
+
+ public static int conflict(ConflictingInterface item) {
+ return 123;
+ }
+}
diff --git a/src/test/examples/classmerging/ConflictingInterface.java b/src/test/examples/classmerging/ConflictingInterface.java
new file mode 100644
index 0000000..6202e3c
--- /dev/null
+++ b/src/test/examples/classmerging/ConflictingInterface.java
@@ -0,0 +1,9 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public interface ConflictingInterface {
+
+ public String method();
+}
diff --git a/src/test/examples/classmerging/ConflictingInterfaceImpl.java b/src/test/examples/classmerging/ConflictingInterfaceImpl.java
new file mode 100644
index 0000000..e46edaf
--- /dev/null
+++ b/src/test/examples/classmerging/ConflictingInterfaceImpl.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public class ConflictingInterfaceImpl implements ConflictingInterface {
+
+ @Override
+ public String method() {
+ return "ConflictingInterfaceImpl::method";
+ }
+}
diff --git a/src/test/examples/classmerging/GenericAbstractClass.java b/src/test/examples/classmerging/GenericAbstractClass.java
new file mode 100644
index 0000000..42620f6
--- /dev/null
+++ b/src/test/examples/classmerging/GenericAbstractClass.java
@@ -0,0 +1,13 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public abstract class GenericAbstractClass<T> {
+
+ public abstract T method();
+
+ public T otherMethod() {
+ return null;
+ }
+}
diff --git a/src/test/examples/classmerging/GenericAbstractClassImpl.java b/src/test/examples/classmerging/GenericAbstractClassImpl.java
new file mode 100644
index 0000000..931465e
--- /dev/null
+++ b/src/test/examples/classmerging/GenericAbstractClassImpl.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public class GenericAbstractClassImpl extends GenericAbstractClass<String> {
+
+ @Override
+ public String method() {
+ return "Hello from GenericAbstractClassImpl";
+ }
+
+ @Override
+ public String otherMethod() {
+ return "otherMethod";
+ }
+}
diff --git a/src/test/examples/classmerging/GenericInterface.java b/src/test/examples/classmerging/GenericInterface.java
new file mode 100644
index 0000000..cda0b32
--- /dev/null
+++ b/src/test/examples/classmerging/GenericInterface.java
@@ -0,0 +1,9 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public interface GenericInterface<T> {
+
+ T method();
+}
diff --git a/src/test/examples/classmerging/GenericInterfaceImpl.java b/src/test/examples/classmerging/GenericInterfaceImpl.java
new file mode 100644
index 0000000..6a14107
--- /dev/null
+++ b/src/test/examples/classmerging/GenericInterfaceImpl.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public class GenericInterfaceImpl implements GenericInterface<String> {
+
+ @Override
+ public String method() {
+ return "method";
+ }
+}
diff --git a/src/test/examples/classmerging/OtherClassWithConflictingMethod.java b/src/test/examples/classmerging/OtherClassWithConflictingMethod.java
new file mode 100644
index 0000000..cd7efd1
--- /dev/null
+++ b/src/test/examples/classmerging/OtherClassWithConflictingMethod.java
@@ -0,0 +1,11 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public class OtherClassWithConflictingMethod {
+
+ public static int conflict(ConflictingInterfaceImpl item) {
+ return 321;
+ }
+}
diff --git a/src/test/examples/classmerging/Outer.java b/src/test/examples/classmerging/Outer.java
new file mode 100644
index 0000000..652f794
--- /dev/null
+++ b/src/test/examples/classmerging/Outer.java
@@ -0,0 +1,26 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+class Outer {
+
+ /**
+ * This class is package private to trigger the generation of bridge methods
+ * for the visibility change of methods from public subtypes.
+ */
+ class SuperClass {
+
+ public String method() {
+ return "Method in SuperClass.";
+ }
+ }
+
+ public class SubClass extends SuperClass {
+ // Intentionally left empty.
+ }
+
+ public SubClass getInstance() {
+ return new SubClass();
+ }
+}
diff --git a/src/test/examples/classmerging/SubClass.java b/src/test/examples/classmerging/SubClass.java
new file mode 100644
index 0000000..b6a9054
--- /dev/null
+++ b/src/test/examples/classmerging/SubClass.java
@@ -0,0 +1,22 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public class SubClass extends SuperClass {
+
+ private int field;
+
+ public SubClass(int field) {
+ this(field, field + 100);
+ }
+
+ public SubClass(int one, int other) {
+ super(one);
+ field = other;
+ }
+
+ public String toString() {
+ return "is " + field + " " + getField();
+ }
+}
diff --git a/src/test/examples/classmerging/SubClassThatReferencesSuperMethod.java b/src/test/examples/classmerging/SubClassThatReferencesSuperMethod.java
new file mode 100644
index 0000000..c12804c
--- /dev/null
+++ b/src/test/examples/classmerging/SubClassThatReferencesSuperMethod.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public class SubClassThatReferencesSuperMethod extends SuperClassWithReferencedMethod {
+
+ @Override
+ public String referencedMethod() {
+ return "From sub: " + super.referencedMethod();
+ }
+}
diff --git a/src/test/examples/classmerging/SuperClass.java b/src/test/examples/classmerging/SuperClass.java
new file mode 100644
index 0000000..b7c9207
--- /dev/null
+++ b/src/test/examples/classmerging/SuperClass.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public class SuperClass {
+
+ private final int field;
+
+ public SuperClass(int field) {
+ this.field = field;
+ }
+
+ public int getField() {
+ return field;
+ }
+}
diff --git a/src/test/examples/classmerging/SuperClassWithReferencedMethod.java b/src/test/examples/classmerging/SuperClassWithReferencedMethod.java
new file mode 100644
index 0000000..8d4e7b5
--- /dev/null
+++ b/src/test/examples/classmerging/SuperClassWithReferencedMethod.java
@@ -0,0 +1,11 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public class SuperClassWithReferencedMethod {
+
+ public String referencedMethod() {
+ return "From Super";
+ }
+}
diff --git a/src/test/examples/classmerging/Test.java b/src/test/examples/classmerging/Test.java
new file mode 100644
index 0000000..6d5c51f
--- /dev/null
+++ b/src/test/examples/classmerging/Test.java
@@ -0,0 +1,34 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package classmerging;
+
+public class Test {
+
+ public static void main(String... args) {
+ GenericInterface iface = new GenericInterfaceImpl();
+ callMethodOnIface(iface);
+ GenericAbstractClass clazz = new GenericAbstractClassImpl();
+ callMethodOnAbstractClass(clazz);
+ ConflictingInterfaceImpl impl = new ConflictingInterfaceImpl();
+ callMethodOnIface(impl);
+ System.out.println(new SubClassThatReferencesSuperMethod().referencedMethod());
+ System.out.println(new Outer().getInstance().method());
+ System.out.println(new SubClass(42));
+ }
+
+ private static void callMethodOnIface(GenericInterface iface) {
+ System.out.println(iface.method());
+ }
+
+ private static void callMethodOnAbstractClass(GenericAbstractClass clazz) {
+ System.out.println(clazz.method());
+ System.out.println(clazz.otherMethod());
+ }
+
+ private static void callMethodOnIface(ConflictingInterface iface) {
+ System.out.println(iface.method());
+ System.out.println(ClassWithConflictingMethod.conflict(null));
+ System.out.println(OtherClassWithConflictingMethod.conflict(null));
+ }
+}
diff --git a/src/test/examples/classmerging/keep-rules.txt b/src/test/examples/classmerging/keep-rules.txt
new file mode 100644
index 0000000..58b262b
--- /dev/null
+++ b/src/test/examples/classmerging/keep-rules.txt
@@ -0,0 +1,12 @@
+# Copyright (c) 2016, 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 the application entry point. Get rid of everything that is not
+# reachable from there.
+-keep public class classmerging.Test {
+ public static void main(...);
+}
+
+# allow access modification to enable minification
+-allowaccessmodification