Wed, 02 Sep 2015 16:35:14 +0200
8134939: Improve toString method of Dynalink DynamicMethod objects
Reviewed-by: hannesw, sundar
1.1 --- a/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java Wed Sep 17 16:44:23 2014 +0400 1.2 +++ b/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java Wed Sep 02 16:35:14 2015 +0200 1.3 @@ -107,7 +107,7 @@ 1.4 private final AccessibleObject target; 1.5 private final MethodType type; 1.6 1.7 - public CallerSensitiveDynamicMethod(final AccessibleObject target) { 1.8 + CallerSensitiveDynamicMethod(final AccessibleObject target) { 1.9 super(getName(target)); 1.10 this.target = target; 1.11 this.type = getMethodType(target); 1.12 @@ -115,8 +115,9 @@ 1.13 1.14 private static String getName(final AccessibleObject target) { 1.15 final Member m = (Member)target; 1.16 - return getMethodNameWithSignature(getMethodType(target), getClassAndMethodName(m.getDeclaringClass(), 1.17 - m.getName())); 1.18 + final boolean constructor = m instanceof Constructor; 1.19 + return getMethodNameWithSignature(getMethodType(target), constructor ? m.getName() : 1.20 + getClassAndMethodName(m.getDeclaringClass(), m.getName()), !constructor); 1.21 } 1.22 1.23 @Override
2.1 --- a/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java Wed Sep 17 16:44:23 2014 +0400 2.2 +++ b/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java Wed Sep 02 16:35:14 2015 +0200 2.3 @@ -86,7 +86,9 @@ 2.4 import java.lang.invoke.MethodHandle; 2.5 import java.lang.invoke.MethodHandles; 2.6 import java.lang.invoke.MethodType; 2.7 +import java.text.Collator; 2.8 import java.util.ArrayList; 2.9 +import java.util.Collections; 2.10 import java.util.Iterator; 2.11 import java.util.LinkedList; 2.12 import java.util.List; 2.13 @@ -242,6 +244,35 @@ 2.14 return methods.getFirst().isConstructor(); 2.15 } 2.16 2.17 + @Override 2.18 + public String toString() { 2.19 + // First gather the names and sort them. This makes it consistent and easier to read. 2.20 + final List<String> names = new ArrayList<>(methods.size()); 2.21 + int len = 0; 2.22 + for (final SingleDynamicMethod m: methods) { 2.23 + final String name = m.getName(); 2.24 + len += name.length(); 2.25 + names.add(name); 2.26 + } 2.27 + // Case insensitive sorting, so e.g. "Object" doesn't come before "boolean". 2.28 + final Collator collator = Collator.getInstance(); 2.29 + collator.setStrength(Collator.SECONDARY); 2.30 + Collections.sort(names, collator); 2.31 + 2.32 + final String className = getClass().getName(); 2.33 + // Class name length + length of signatures + 2 chars/per signature for indentation and newline + 2.34 + // 3 for brackets and initial newline 2.35 + final int totalLength = className.length() + len + 2 * names.size() + 3; 2.36 + final StringBuilder b = new StringBuilder(totalLength); 2.37 + b.append('[').append(className).append('\n'); 2.38 + for(final String name: names) { 2.39 + b.append(' ').append(name).append('\n'); 2.40 + } 2.41 + b.append(']'); 2.42 + assert b.length() == totalLength; 2.43 + return b.toString(); 2.44 + }; 2.45 + 2.46 ClassLoader getClassLoader() { 2.47 return classLoader; 2.48 }
3.1 --- a/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java Wed Sep 17 16:44:23 2014 +0400 3.2 +++ b/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java Wed Sep 02 16:35:14 2015 +0200 3.3 @@ -122,13 +122,13 @@ 3.4 * @param constructor does this represent a constructor? 3.5 */ 3.6 SimpleDynamicMethod(final MethodHandle target, final Class<?> clazz, final String name, final boolean constructor) { 3.7 - super(getName(target, clazz, name)); 3.8 + super(getName(target, clazz, name, constructor)); 3.9 this.target = target; 3.10 this.constructor = constructor; 3.11 } 3.12 3.13 - private static String getName(final MethodHandle target, final Class<?> clazz, final String name) { 3.14 - return getMethodNameWithSignature(target.type(), getClassAndMethodName(clazz, name)); 3.15 + private static String getName(final MethodHandle target, final Class<?> clazz, final String name, final boolean constructor) { 3.16 + return getMethodNameWithSignature(target.type(), constructor ? name : getClassAndMethodName(clazz, name), !constructor); 3.17 } 3.18 3.19 @Override
4.1 --- a/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java Wed Sep 17 16:44:23 2014 +0400 4.2 +++ b/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java Wed Sep 02 16:35:14 2015 +0200 4.3 @@ -142,14 +142,18 @@ 4.4 return getMethodType().parameterList().equals(method.getMethodType().parameterList()); 4.5 } 4.6 4.7 - static String getMethodNameWithSignature(final MethodType type, final String methodName) { 4.8 + static String getMethodNameWithSignature(final MethodType type, final String methodName, final boolean withReturnType) { 4.9 final String typeStr = type.toString(); 4.10 final int retTypeIndex = typeStr.lastIndexOf(')') + 1; 4.11 int secondParamIndex = typeStr.indexOf(',') + 1; 4.12 if(secondParamIndex == 0) { 4.13 secondParamIndex = retTypeIndex - 1; 4.14 } 4.15 - return typeStr.substring(retTypeIndex) + " " + methodName + "(" + typeStr.substring(secondParamIndex, retTypeIndex); 4.16 + final StringBuilder b = new StringBuilder(); 4.17 + if (withReturnType) { 4.18 + b.append(typeStr, retTypeIndex, typeStr.length()).append(' '); 4.19 + } 4.20 + return b.append(methodName).append('(').append(typeStr, secondParamIndex, retTypeIndex).toString(); 4.21 } 4.22 4.23 /**
5.1 --- a/test/script/basic/JDK-8043232.js.EXPECTED Wed Sep 17 16:44:23 2014 +0400 5.2 +++ b/test/script/basic/JDK-8043232.js.EXPECTED Wed Sep 02 16:35:14 2015 +0200 5.3 @@ -1,14 +1,28 @@ 5.4 bcd 5.5 -[jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] 5.6 +[jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] 5.7 red 5.8 TypeError: No such Java class: java.lang.NonExistent 5.9 TypeError: No such Java constructor: Object(String) 5.10 TypeError: Java constructor signature invalid: Object()xxxxx 5.11 TypeError: Java constructor signature invalid: Object( 5.12 TypeError: Java constructor signature invalid: Object) 5.13 -TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.lang.System.getProperty] cannot be used as a constructor. 5.14 -TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] cannot be used as a constructor. 5.15 -TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] requires "new". 5.16 +TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod 5.17 + String java.lang.System.getProperty(String,String) 5.18 + String java.lang.System.getProperty(String) 5.19 +] cannot be used as a constructor. 5.20 +TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod 5.21 + void java.io.PrintStream.println() 5.22 + void java.io.PrintStream.println(boolean) 5.23 + void java.io.PrintStream.println(char) 5.24 + void java.io.PrintStream.println(char[]) 5.25 + void java.io.PrintStream.println(double) 5.26 + void java.io.PrintStream.println(float) 5.27 + void java.io.PrintStream.println(int) 5.28 + void java.io.PrintStream.println(long) 5.29 + void java.io.PrintStream.println(Object) 5.30 + void java.io.PrintStream.println(String) 5.31 +] cannot be used as a constructor. 5.32 +TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] requires "new". 5.33 TypeError: No such Java constructor: Runnable() 5.34 TypeError: No such Java constructor: Runnable(int) 5.35 java.lang.InstantiationException: java.io.InputStream
6.1 --- a/test/script/basic/JDK-8049242.js.EXPECTED Wed Sep 17 16:44:23 2014 +0400 6.2 +++ b/test/script/basic/JDK-8049242.js.EXPECTED Wed Sep 02 16:35:14 2015 +0200 6.3 @@ -1,10 +1,10 @@ 6.4 abc 6.5 -[jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] 6.6 +[jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] 6.7 ava 6.8 TypeError: null is not a function 6.9 TypeError: null is not a function 6.10 TypeError: null is not a function 6.11 -TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] requires "new". 6.12 +TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] requires "new". 6.13 TypeError: null is not a function 6.14 TypeError: null is not a function 6.15 java.lang.InstantiationException: java.io.InputStream
7.1 --- a/test/script/basic/JDK-8079470.js.EXPECTED Wed Sep 17 16:44:23 2014 +0400 7.2 +++ b/test/script/basic/JDK-8079470.js.EXPECTED Wed Sep 02 16:35:14 2015 +0200 7.3 @@ -1,2 +1,2 @@ 7.4 -TypeError: Can not create new object with constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod File java.io.File.java.io.File(String,String)] with the passed arguments; they do not match any of its method signatures. 7.5 -TypeError: Can not create new object with constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] with the passed arguments; they do not match any of its method signatures. 7.6 +TypeError: Can not create new object with constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod java.io.File(String,String)] with the passed arguments; they do not match any of its method signatures. 7.7 +TypeError: Can not create new object with constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod java.awt.Color(int,int,int)] with the passed arguments; they do not match any of its method signatures.
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/test/script/basic/JDK-8134939.js Wed Sep 02 16:35:14 2015 +0200 8.3 @@ -0,0 +1,43 @@ 8.4 +/* 8.5 + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. 8.11 + * 8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.15 + * version 2 for more details (a copy is included in the LICENSE file that 8.16 + * accompanied this code). 8.17 + * 8.18 + * You should have received a copy of the GNU General Public License version 8.19 + * 2 along with this work; if not, write to the Free Software Foundation, 8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.21 + * 8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.23 + * or visit www.oracle.com if you need additional information or have any 8.24 + * questions. 8.25 + */ 8.26 + 8.27 +/** 8.28 + * JDK-8134939: Improve toString method of Dynalink OverloadedDynamicMethod 8.29 + * 8.30 + * @test 8.31 + * @run 8.32 + */ 8.33 + 8.34 +var overloadedSetter = new (Java.type("jdk.nashorn.test.models.OverloadedSetter")); 8.35 + 8.36 +Assert.assertEquals(String(overloadedSetter.foo), 8.37 + "[jdk.internal.dynalink.beans.OverloadedDynamicMethod\n" + 8.38 + " String jdk.nashorn.test.models.OverloadedSetter.foo(String)\n" + 8.39 + " void jdk.nashorn.test.models.OverloadedSetter.foo(int)\n" + 8.40 + "]"); 8.41 + 8.42 +Assert.assertEquals(String(overloadedSetter.setColor), 8.43 + "[jdk.internal.dynalink.beans.OverloadedDynamicMethod\n" + 8.44 + " void jdk.nashorn.test.models.OverloadedSetter.setColor(int)\n" + 8.45 + " void jdk.nashorn.test.models.OverloadedSetter.setColor(String)\n" + 8.46 + "]");
9.1 --- a/test/script/trusted/classfilter.js.EXPECTED Wed Sep 17 16:44:23 2014 +0400 9.2 +++ b/test/script/trusted/classfilter.js.EXPECTED Wed Sep 02 16:35:14 2015 +0200 9.3 @@ -4,7 +4,18 @@ 9.4 typeof java.util.Map evalutes to function 9.5 typeof java.util.HashMap evalutes to function 9.6 var m = new java.util.HashMap(); m.put('foo', 42); m evalutes to {foo=42} 9.7 -java.lang.System.out.println evalutes to [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] 9.8 +java.lang.System.out.println evalutes to [jdk.internal.dynalink.beans.OverloadedDynamicMethod 9.9 + void java.io.PrintStream.println() 9.10 + void java.io.PrintStream.println(boolean) 9.11 + void java.io.PrintStream.println(char) 9.12 + void java.io.PrintStream.println(char[]) 9.13 + void java.io.PrintStream.println(double) 9.14 + void java.io.PrintStream.println(float) 9.15 + void java.io.PrintStream.println(int) 9.16 + void java.io.PrintStream.println(long) 9.17 + void java.io.PrintStream.println(Object) 9.18 + void java.io.PrintStream.println(String) 9.19 +] 9.20 java.lang.System.exit evalutes to [jdk.internal.dynalink.beans.SimpleDynamicMethod void java.lang.System.exit(int)] 9.21 new javax.script.SimpleBindings throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.SimpleBindings 9.22 Java.type('javax.script.ScriptContext') throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.ScriptContext