8134939: Improve toString method of Dynalink DynamicMethod objects

Wed, 02 Sep 2015 16:35:14 +0200

author
attila
date
Wed, 02 Sep 2015 16:35:14 +0200
changeset 1539
684d430470f6
parent 1538
82a41eb20242
child 1540
5678c4914917

8134939: Improve toString method of Dynalink DynamicMethod objects
Reviewed-by: hannesw, sundar

src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java file | annotate | diff | comparison | revisions
src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java file | annotate | diff | comparison | revisions
src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java file | annotate | diff | comparison | revisions
src/jdk/internal/dynalink/beans/SingleDynamicMethod.java file | annotate | diff | comparison | revisions
test/script/basic/JDK-8043232.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/JDK-8049242.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/JDK-8079470.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/JDK-8134939.js file | annotate | diff | comparison | revisions
test/script/trusted/classfilter.js.EXPECTED file | annotate | diff | comparison | revisions
     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

mercurial