# HG changeset patch # User attila # Date 1441204514 -7200 # Node ID 684d430470f69ed2cb286054dee712725120e4ea # Parent 82a41eb20242abab8b75538e02cc818290a127d6 8134939: Improve toString method of Dynalink DynamicMethod objects Reviewed-by: hannesw, sundar diff -r 82a41eb20242 -r 684d430470f6 src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java --- a/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java Wed Sep 17 16:44:23 2014 +0400 +++ b/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java Wed Sep 02 16:35:14 2015 +0200 @@ -107,7 +107,7 @@ private final AccessibleObject target; private final MethodType type; - public CallerSensitiveDynamicMethod(final AccessibleObject target) { + CallerSensitiveDynamicMethod(final AccessibleObject target) { super(getName(target)); this.target = target; this.type = getMethodType(target); @@ -115,8 +115,9 @@ private static String getName(final AccessibleObject target) { final Member m = (Member)target; - return getMethodNameWithSignature(getMethodType(target), getClassAndMethodName(m.getDeclaringClass(), - m.getName())); + final boolean constructor = m instanceof Constructor; + return getMethodNameWithSignature(getMethodType(target), constructor ? m.getName() : + getClassAndMethodName(m.getDeclaringClass(), m.getName()), !constructor); } @Override diff -r 82a41eb20242 -r 684d430470f6 src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java --- a/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java Wed Sep 17 16:44:23 2014 +0400 +++ b/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java Wed Sep 02 16:35:14 2015 +0200 @@ -86,7 +86,9 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.text.Collator; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -242,6 +244,35 @@ return methods.getFirst().isConstructor(); } + @Override + public String toString() { + // First gather the names and sort them. This makes it consistent and easier to read. + final List names = new ArrayList<>(methods.size()); + int len = 0; + for (final SingleDynamicMethod m: methods) { + final String name = m.getName(); + len += name.length(); + names.add(name); + } + // Case insensitive sorting, so e.g. "Object" doesn't come before "boolean". + final Collator collator = Collator.getInstance(); + collator.setStrength(Collator.SECONDARY); + Collections.sort(names, collator); + + final String className = getClass().getName(); + // Class name length + length of signatures + 2 chars/per signature for indentation and newline + + // 3 for brackets and initial newline + final int totalLength = className.length() + len + 2 * names.size() + 3; + final StringBuilder b = new StringBuilder(totalLength); + b.append('[').append(className).append('\n'); + for(final String name: names) { + b.append(' ').append(name).append('\n'); + } + b.append(']'); + assert b.length() == totalLength; + return b.toString(); + }; + ClassLoader getClassLoader() { return classLoader; } diff -r 82a41eb20242 -r 684d430470f6 src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java --- a/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java Wed Sep 17 16:44:23 2014 +0400 +++ b/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java Wed Sep 02 16:35:14 2015 +0200 @@ -122,13 +122,13 @@ * @param constructor does this represent a constructor? */ SimpleDynamicMethod(final MethodHandle target, final Class clazz, final String name, final boolean constructor) { - super(getName(target, clazz, name)); + super(getName(target, clazz, name, constructor)); this.target = target; this.constructor = constructor; } - private static String getName(final MethodHandle target, final Class clazz, final String name) { - return getMethodNameWithSignature(target.type(), getClassAndMethodName(clazz, name)); + private static String getName(final MethodHandle target, final Class clazz, final String name, final boolean constructor) { + return getMethodNameWithSignature(target.type(), constructor ? name : getClassAndMethodName(clazz, name), !constructor); } @Override diff -r 82a41eb20242 -r 684d430470f6 src/jdk/internal/dynalink/beans/SingleDynamicMethod.java --- a/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java Wed Sep 17 16:44:23 2014 +0400 +++ b/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java Wed Sep 02 16:35:14 2015 +0200 @@ -142,14 +142,18 @@ return getMethodType().parameterList().equals(method.getMethodType().parameterList()); } - static String getMethodNameWithSignature(final MethodType type, final String methodName) { + static String getMethodNameWithSignature(final MethodType type, final String methodName, final boolean withReturnType) { final String typeStr = type.toString(); final int retTypeIndex = typeStr.lastIndexOf(')') + 1; int secondParamIndex = typeStr.indexOf(',') + 1; if(secondParamIndex == 0) { secondParamIndex = retTypeIndex - 1; } - return typeStr.substring(retTypeIndex) + " " + methodName + "(" + typeStr.substring(secondParamIndex, retTypeIndex); + final StringBuilder b = new StringBuilder(); + if (withReturnType) { + b.append(typeStr, retTypeIndex, typeStr.length()).append(' '); + } + return b.append(methodName).append('(').append(typeStr, secondParamIndex, retTypeIndex).toString(); } /** diff -r 82a41eb20242 -r 684d430470f6 test/script/basic/JDK-8043232.js.EXPECTED --- a/test/script/basic/JDK-8043232.js.EXPECTED Wed Sep 17 16:44:23 2014 +0400 +++ b/test/script/basic/JDK-8043232.js.EXPECTED Wed Sep 02 16:35:14 2015 +0200 @@ -1,14 +1,28 @@ bcd -[jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] +[jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] red TypeError: No such Java class: java.lang.NonExistent TypeError: No such Java constructor: Object(String) TypeError: Java constructor signature invalid: Object()xxxxx TypeError: Java constructor signature invalid: Object( TypeError: Java constructor signature invalid: Object) -TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.lang.System.getProperty] cannot be used as a constructor. -TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] cannot be used as a constructor. -TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] requires "new". +TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod + String java.lang.System.getProperty(String,String) + String java.lang.System.getProperty(String) +] cannot be used as a constructor. +TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod + void java.io.PrintStream.println() + void java.io.PrintStream.println(boolean) + void java.io.PrintStream.println(char) + void java.io.PrintStream.println(char[]) + void java.io.PrintStream.println(double) + void java.io.PrintStream.println(float) + void java.io.PrintStream.println(int) + void java.io.PrintStream.println(long) + void java.io.PrintStream.println(Object) + void java.io.PrintStream.println(String) +] cannot be used as a constructor. +TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] requires "new". TypeError: No such Java constructor: Runnable() TypeError: No such Java constructor: Runnable(int) java.lang.InstantiationException: java.io.InputStream diff -r 82a41eb20242 -r 684d430470f6 test/script/basic/JDK-8049242.js.EXPECTED --- a/test/script/basic/JDK-8049242.js.EXPECTED Wed Sep 17 16:44:23 2014 +0400 +++ b/test/script/basic/JDK-8049242.js.EXPECTED Wed Sep 02 16:35:14 2015 +0200 @@ -1,10 +1,10 @@ abc -[jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] +[jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] ava TypeError: null is not a function TypeError: null is not a function TypeError: null is not a function -TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] requires "new". +TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] requires "new". TypeError: null is not a function TypeError: null is not a function java.lang.InstantiationException: java.io.InputStream diff -r 82a41eb20242 -r 684d430470f6 test/script/basic/JDK-8079470.js.EXPECTED --- a/test/script/basic/JDK-8079470.js.EXPECTED Wed Sep 17 16:44:23 2014 +0400 +++ b/test/script/basic/JDK-8079470.js.EXPECTED Wed Sep 02 16:35:14 2015 +0200 @@ -1,2 +1,2 @@ -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. -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. +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. +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. diff -r 82a41eb20242 -r 684d430470f6 test/script/basic/JDK-8134939.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8134939.js Wed Sep 02 16:35:14 2015 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * JDK-8134939: Improve toString method of Dynalink OverloadedDynamicMethod + * + * @test + * @run + */ + +var overloadedSetter = new (Java.type("jdk.nashorn.test.models.OverloadedSetter")); + +Assert.assertEquals(String(overloadedSetter.foo), + "[jdk.internal.dynalink.beans.OverloadedDynamicMethod\n" + + " String jdk.nashorn.test.models.OverloadedSetter.foo(String)\n" + + " void jdk.nashorn.test.models.OverloadedSetter.foo(int)\n" + + "]"); + +Assert.assertEquals(String(overloadedSetter.setColor), + "[jdk.internal.dynalink.beans.OverloadedDynamicMethod\n" + + " void jdk.nashorn.test.models.OverloadedSetter.setColor(int)\n" + + " void jdk.nashorn.test.models.OverloadedSetter.setColor(String)\n" + + "]"); diff -r 82a41eb20242 -r 684d430470f6 test/script/trusted/classfilter.js.EXPECTED --- a/test/script/trusted/classfilter.js.EXPECTED Wed Sep 17 16:44:23 2014 +0400 +++ b/test/script/trusted/classfilter.js.EXPECTED Wed Sep 02 16:35:14 2015 +0200 @@ -4,7 +4,18 @@ typeof java.util.Map evalutes to function typeof java.util.HashMap evalutes to function var m = new java.util.HashMap(); m.put('foo', 42); m evalutes to {foo=42} -java.lang.System.out.println evalutes to [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] +java.lang.System.out.println evalutes to [jdk.internal.dynalink.beans.OverloadedDynamicMethod + void java.io.PrintStream.println() + void java.io.PrintStream.println(boolean) + void java.io.PrintStream.println(char) + void java.io.PrintStream.println(char[]) + void java.io.PrintStream.println(double) + void java.io.PrintStream.println(float) + void java.io.PrintStream.println(int) + void java.io.PrintStream.println(long) + void java.io.PrintStream.println(Object) + void java.io.PrintStream.println(String) +] java.lang.System.exit evalutes to [jdk.internal.dynalink.beans.SimpleDynamicMethod void java.lang.System.exit(int)] new javax.script.SimpleBindings throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.SimpleBindings Java.type('javax.script.ScriptContext') throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.ScriptContext