Allow obfuscation of generic signature

Bug: 38188583
Change-Id: I08ed683c04731965915d4f3fa2e0649ee6775ab6
diff --git a/src/test/examples/minifygeneric/AA.java b/src/test/examples/minifygeneric/AA.java
new file mode 100644
index 0000000..66b7aaf8
--- /dev/null
+++ b/src/test/examples/minifygeneric/AA.java
@@ -0,0 +1,7 @@
+// 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 minifygeneric;
+
+public class AA {
+}
diff --git a/src/test/examples/minifygeneric/BB.java b/src/test/examples/minifygeneric/BB.java
new file mode 100644
index 0000000..c29ca97
--- /dev/null
+++ b/src/test/examples/minifygeneric/BB.java
@@ -0,0 +1,7 @@
+// 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 minifygeneric;
+
+public class BB {
+}
diff --git a/src/test/examples/minifygeneric/Generic.java b/src/test/examples/minifygeneric/Generic.java
new file mode 100644
index 0000000..53f9e3d
--- /dev/null
+++ b/src/test/examples/minifygeneric/Generic.java
@@ -0,0 +1,32 @@
+// 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 minifygeneric;
+
+import java.util.List;
+import java.util.Map;
+
+public class Generic<T extends AA> {
+
+  public <U extends List> T m (Object o, T[] t, Map<T,U> m) {
+    return null;
+  }
+
+  public <U extends Map> T m2 (Object o, T[] t, Map<T,U> m) {
+    return null;
+  }
+
+  public <U extends List> T m3 (Object o, T t, Map<T,U> m) {
+    return null;
+  }
+
+  public <U extends List> T m4 (Object o, T[] t, List<U> m) {
+    return null;
+  }
+
+  public Generic<T> f;
+  public Generic<T> get() {
+    return this;
+  }
+
+}
diff --git a/src/test/examples/minifygeneric/Minifygeneric.java b/src/test/examples/minifygeneric/Minifygeneric.java
new file mode 100644
index 0000000..36406bb
--- /dev/null
+++ b/src/test/examples/minifygeneric/Minifygeneric.java
@@ -0,0 +1,42 @@
+// 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 minifygeneric;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+public class Minifygeneric {
+
+  public static void main(String[] args) throws NoSuchMethodException, SecurityException, NoSuchFieldException {
+    for (TypeVariable<Class<Generic>> var : Generic.class.getTypeParameters()) {
+      System.out.println(var.getName());
+      Type bound = var.getBounds()[0];
+      System.out.println(((Class<?>) bound).getName().equals(AA.class.getName()));
+    }
+
+    Field f = Generic.class.getField("f");
+    ParameterizedType fieldType = (java.lang.reflect.ParameterizedType)f.getGenericType();
+    checkOneParameterType(fieldType, Generic.class, AA.class);
+
+    ParameterizedType methodReturnType =
+        (ParameterizedType) Generic.class.getMethod("get").getGenericReturnType();
+    checkOneParameterType(methodReturnType, Generic.class, AA.class);
+  }
+
+  private static void checkOneParameterType(ParameterizedType toCheck, Class<?> rawType,
+      Class<?>... bounds) {
+    System.out.println(((Class<?>) toCheck.getRawType()).getName()
+        .equals(rawType.getName()));
+    Type[] parameters = toCheck.getActualTypeArguments();
+    System.out.println(parameters.length);
+    TypeVariable<?> parameter = (TypeVariable<?>) parameters[0];
+    System.out.println(parameter.getName());
+    Type[] actualBounds = parameter.getBounds();
+    for (int i = 0; i < bounds.length; i++) {
+      System.out.println(((Class<?>) actualBounds[i]).getName().equals(bounds[i].getName()));
+    }
+  }
+}
diff --git a/src/test/examples/minifygeneric/keep-rules.txt b/src/test/examples/minifygeneric/keep-rules.txt
new file mode 100644
index 0000000..741d5c3
--- /dev/null
+++ b/src/test/examples/minifygeneric/keep-rules.txt
@@ -0,0 +1,15 @@
+# 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.
+
+-keep,allowobfuscation class ** {
+*;
+}
+-keep class *.Minifygeneric {
+*;
+}
+-keepclassmembernames class *.Generic {
+*;
+}
+-keepattributes *
+-allowaccessmodification
diff --git a/src/test/examples/minifygenericwithinner/AA.java b/src/test/examples/minifygenericwithinner/AA.java
new file mode 100644
index 0000000..ff283da
--- /dev/null
+++ b/src/test/examples/minifygenericwithinner/AA.java
@@ -0,0 +1,7 @@
+// 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 minifygenericwithinner;
+
+public class AA {
+}
diff --git a/src/test/examples/minifygenericwithinner/BB.java b/src/test/examples/minifygenericwithinner/BB.java
new file mode 100644
index 0000000..31ceb33
--- /dev/null
+++ b/src/test/examples/minifygenericwithinner/BB.java
@@ -0,0 +1,7 @@
+// 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 minifygenericwithinner;
+
+public class BB {
+}
diff --git a/src/test/examples/minifygenericwithinner/Generic.java b/src/test/examples/minifygenericwithinner/Generic.java
new file mode 100644
index 0000000..203561e
--- /dev/null
+++ b/src/test/examples/minifygenericwithinner/Generic.java
@@ -0,0 +1,42 @@
+// 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 minifygenericwithinner;
+
+import java.util.List;
+import java.util.Map;
+
+public class Generic<T extends AA> {
+
+  public <U extends List> T m (Object o, T[] t, Map<T,U> m) {
+    return null;
+  }
+
+  public <U extends Map> T m2 (Object o, T[] t, Map<T,U> m) {
+    return null;
+  }
+
+  public <U extends List> T m3 (Object o, T t, Map<T,U> m) {
+    return null;
+  }
+
+  public <U extends List> T m4 (Object o, T[] t, List<U> m) {
+    return null;
+  }
+
+  public <V extends BB> Inner<V> getInner(V obj) {
+    return new Inner<>();
+  }
+
+  public class Inner<V extends BB> {
+
+    public Generic<T>.Inner<V> f;
+    public <U extends List> T m5 (V o, T[] t, Map<T,U> m) {
+      return m(o, t, m);
+    }
+
+   public Generic<T>.Inner<V> get() {
+      return this;
+    }
+  }
+}
diff --git a/src/test/examples/minifygenericwithinner/Minifygenericwithinner.java b/src/test/examples/minifygenericwithinner/Minifygenericwithinner.java
new file mode 100644
index 0000000..882fa83
--- /dev/null
+++ b/src/test/examples/minifygenericwithinner/Minifygenericwithinner.java
@@ -0,0 +1,52 @@
+// 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 minifygenericwithinner;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+public class Minifygenericwithinner {
+
+  public static void main(String[] args)
+      throws NoSuchMethodException, SecurityException, NoSuchFieldException {
+    for (TypeVariable<Class<Generic>> var : Generic.class.getTypeParameters()) {
+      System.out.println(var.getName());
+      Type bound = var.getBounds()[0];
+      System.out.println(((Class<?>) bound).getName().equals(AA.class.getName()));
+    }
+    for (TypeVariable<Class<Generic.Inner>> var : Generic.Inner.class.getTypeParameters()) {
+      System.out.println(var.getName());
+      Type bound = var.getBounds()[0];
+      System.out.println(((Class<?>) bound).getName().equals(BB.class.getName()));
+    }
+
+    Field f = Generic.Inner.class.getField("f");
+    ParameterizedType fieldType = (java.lang.reflect.ParameterizedType)f.getGenericType();
+    checkOneParameterType(fieldType, Generic.Inner.class, BB.class);
+    ParameterizedType ownerType = (ParameterizedType) fieldType.getOwnerType();
+    checkOneParameterType(ownerType, Generic.class, AA.class);
+
+    ParameterizedType methodReturnType =
+        (ParameterizedType) Generic.Inner.class.getMethod("get").getGenericReturnType();
+    checkOneParameterType(methodReturnType, Generic.Inner.class, BB.class);
+    ownerType = (ParameterizedType) methodReturnType.getOwnerType();
+    checkOneParameterType(ownerType, Generic.class, AA.class);
+  }
+
+  private static void checkOneParameterType(ParameterizedType toCheck, Class<?> rawType,
+      Class<?>... bounds) {
+    System.out.println(((Class<?>) toCheck.getRawType()).getName()
+        .equals(rawType.getName()));
+    Type[] parameters = toCheck.getActualTypeArguments();
+    System.out.println(parameters.length);
+    TypeVariable<?> parameter = (TypeVariable<?>) parameters[0];
+    System.out.println(parameter.getName());
+    Type[] actualBounds = parameter.getBounds();
+    for (int i = 0; i < bounds.length; i++) {
+      System.out.println(((Class<?>) actualBounds[i]).getName().equals(bounds[i].getName()));
+    }
+  }
+}
diff --git a/src/test/examples/minifygenericwithinner/keep-rules.txt b/src/test/examples/minifygenericwithinner/keep-rules.txt
new file mode 100644
index 0000000..357b321
--- /dev/null
+++ b/src/test/examples/minifygenericwithinner/keep-rules.txt
@@ -0,0 +1,16 @@
+# 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.
+
+-keep,allowobfuscation class ** {
+*;
+}
+-keep class *.Minifygenericwithinner {
+*;
+}
+-keepclassmembernames class *.Generic$* {
+*;
+}
+
+-keepattributes *
+-allowaccessmodification