Hi all,

bug https://bugs.openjdk.java.net/browse/JDK-8054213

I have reworked previous patch to conform with JLS 13.1 paragraph 1 and
also JVMS 4.2.1. For now
in case of parametrized types inner type name consists of normal binary
name of immediately
enclosing type, followed by $, followed by simple name of the member type.

Patch with changes attached. I am looking for reviews and for sponsor to
push this one.

Thanks,
Sergey.

2016-03-12 18:41 GMT+03:00 Sergey Ustimenko <merke...@gmail.com>:

> Hi all,
>
> Please review this patch. I'm also looking for sponsor for this one.
>
> The unexpected duplication of owner type was produced by Method.toString()
> for static
> classes and interfaces. Problem is fixed by slightly changing the way of
> obtaining
> simple name of static nested type and concatenating it with owner type.
>
>
> diff --git
> a/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
> b/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
> ---
> a/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
> +++
> b/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
> @@ -212,15 +212,14 @@
>              else
>                  sb.append(ownerType.toString());
>
> -            sb.append(".");
> -
> -            if (ownerType instanceof ParameterizedTypeImpl) {
> +            if (ownerType instanceof ParameterizedTypeImpl)
>                  // Find simple name of nested type by removing the
>                  // shared prefix with owner.
> -                sb.append(rawType.getName().replace(
> ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$",
> -                                         ""));
> -            } else
> -                sb.append(rawType.getName());
> +                sb.append(".").append(
> +
>  
> rawType.getName().replace(((ParameterizedTypeImpl)ownerType).rawType.getName()
> + "$", "")
> +                );
> +            else
> +                sb.append("$").append(rawType.getSimpleName());
>          } else
>              sb.append(rawType.getName());
>
> diff --git a/test/java/lang/reflect/Method/TestReturnTypeDuplication.java
> b/test/java/lang/reflect/Method/TestReturnTypeDuplication.java
> new file mode 100644
> --- /dev/null
> +++ b/test/java/lang/reflect/Method/TestReturnTypeDuplication.java
> @@ -0,0 +1,72 @@
> +/*
> + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 only, as
> + * published by the Free Software Foundation.
> + *
> + * This code is distributed in the hope that it will be useful, but
> WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> + * version 2 for more details (a copy is included in the LICENSE file that
> + * accompanied this code).
> + *
> + * You should have received a copy of the GNU General Public License
> version
> + * 2 along with this work; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
> + * or visit www.oracle.com if you need additional information or have any
> + * questions.
> + */
> +
> +/*
> + * @test
> + * @bug 8054213
> + * @summary Check that Type.toString() generates valid
> + * output for static classes and interfaces
> + * @author Sergey Ustimenko
> + */
> +public class TestReturnTypeDuplication {
> +
> +    private static final String[] SIGNATURES = {
> +            "TestReturnTypeDuplication$Static",
> +
>  "TestReturnTypeDuplication$StaticParametrised<java.lang.String>",
> +            "TestReturnTypeDuplication$Interface",
> +
>  "TestReturnTypeDuplication$InterfaceParametrised<java.lang.String>"
> +    };
> +
> +
> +    public static void main(String[] args) throws Exception {
> +        boolean passed =
> SIGNATURES[0].equals(getFooGenericReturnType("foo0")) &&
> +                SIGNATURES[1].equals(getFooGenericReturnType("foo1")) &&
> +                SIGNATURES[2].equals(getFooGenericReturnType("foo2")) &&
> +                SIGNATURES[3].equals(getFooGenericReturnType("foo3"));
> +
> +        if(!passed) {
> +            throw new RuntimeException("Generated type names are
> invalid!");
> +        }
> +    }
> +
> +    private static String getFooGenericReturnType(String foo) throws
> Exception {
> +        return
> TestReturnTypeDuplication.class.getMethod(foo).getGenericReturnType().getTypeName();
> +    }
> +
> +    static class Static {}
> +
> +    static class StaticParametrised<T> {}
> +
> +    interface Interface {}
> +
> +    interface InterfaceParametrised<T> {}
> +
> +    public TestReturnTypeDuplication.Static foo0(){return null;}
> +
> +    public TestReturnTypeDuplication.StaticParametrised<String>
> foo1(){return null;}
> +
> +    public TestReturnTypeDuplication.Interface foo2(){return null;}
> +
> +    public TestReturnTypeDuplication.InterfaceParametrised<String>
> foo3(){return null;}
> +
> +}
>
diff --git 
a/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
 
b/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
--- 
a/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
+++ 
b/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,7 @@
 
 package sun.reflect.generics.reflectiveObjects;
 
-import sun.reflect.generics.tree.FieldTypeSignature;
-
 import java.lang.reflect.MalformedParameterizedTypeException;
-import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
@@ -212,15 +209,16 @@
             else
                 sb.append(ownerType.toString());
 
-            sb.append(".");
+            sb.append("$");
 
-            if (ownerType instanceof ParameterizedTypeImpl) {
+            if (ownerType instanceof ParameterizedTypeImpl)
                 // Find simple name of nested type by removing the
                 // shared prefix with owner.
-                sb.append(rawType.getName().replace( 
((ParameterizedTypeImpl)ownerType).rawType.getName() + "$",
-                                         ""));
-            } else
-                sb.append(rawType.getName());
+                sb.append(
+                        rawType.getName().replace(((ParameterizedTypeImpl) 
ownerType).rawType.getName() + "$", "")
+                );
+            else
+                sb.append(rawType.getSimpleName());
         } else
             sb.append(rawType.getName());
 
diff --git a/test/java/lang/reflect/Method/TestReturnTypeDuplication.java 
b/test/java/lang/reflect/Method/TestReturnTypeDuplication.java
new file mode 100644
--- /dev/null
+++ b/test/java/lang/reflect/Method/TestReturnTypeDuplication.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8054213
+ * @summary Check that Type.toString() generates valid
+ * output for static classes and interfaces
+ * @author Sergey Ustimenko
+ */
+public class TestReturnTypeDuplication<F> {
+
+    private static final String[] SIGNATURES = {
+            "TestReturnTypeDuplication$Static$A",
+            "TestReturnTypeDuplication$StaticParametrised<java.lang.String>$A",
+            "TestReturnTypeDuplication$Interface",
+            
"TestReturnTypeDuplication$InterfaceParametrised<java.lang.String>",
+            "TestReturnTypeDuplication<java.lang.String>$Inner$A",
+            
"TestReturnTypeDuplication<java.lang.String>$InnerParametrised<java.lang.String>$A"
+    };
+
+
+    public static void main(String[] args) throws Exception {
+        check(SIGNATURES[0], getFooGenericReturnType("foo0"));
+        check(SIGNATURES[1], getFooGenericReturnType("foo1"));
+        check(SIGNATURES[2], getFooGenericReturnType("foo2"));
+        check(SIGNATURES[3], getFooGenericReturnType("foo3"));
+        check(SIGNATURES[4], getFooGenericReturnType("foo4"));
+        check(SIGNATURES[5], getFooGenericReturnType("foo5"));
+    }
+
+    private static void check(String expected, String actual) {
+        if (!expected.equals(actual)) {
+            throw new RuntimeException(String.format("TypeName invalid! 
Expected {%s}, got {%s}", expected, actual));
+        }
+    }
+
+    private static String getFooGenericReturnType(String foo) throws Exception 
{
+        return 
TestReturnTypeDuplication.class.getMethod(foo).getGenericReturnType().getTypeName();
+    }
+
+    class Inner {class A{}}
+
+    class InnerParametrised<T> {class A{}}
+
+    static class Static {class A{}}
+
+    static class StaticParametrised<T> {class A{}}
+
+    interface Interface {}
+
+    interface InterfaceParametrised<T> {}
+
+    public TestReturnTypeDuplication.Static.A foo0(){return null;}
+
+    public TestReturnTypeDuplication.StaticParametrised<String>.A 
foo1(){return null;}
+
+    public TestReturnTypeDuplication.Interface foo2(){return null;}
+
+    public TestReturnTypeDuplication.InterfaceParametrised<String> 
foo3(){return null;}
+
+    public TestReturnTypeDuplication<String>.Inner.A foo4(){return null;}
+
+    public TestReturnTypeDuplication<String>.InnerParametrised<String>.A 
foo5(){return null;}
+
+}

Reply via email to