Forgot to attach a patch 2016-03-17 15:13 GMT+03:00 Sergey Ustimenko <merke...@gmail.com>:
> Hi all, > > bug https://bugs.openjdk.java.net/browse/JDK-8054213 > > This fix modifies behavior of Type.to String() 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 $ and > finally followed > by simple name of the member type. > > Patch with changes and jtreg test attached. I am looking for reviews and > for sponsor to > push this one. > > Thanks, > Sergey. > -Sergey
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;} + +}