8007286: Add JavaAdapter and importPackage to compatibility script

Thu, 31 Jan 2013 20:07:40 +0530

author
sundar
date
Thu, 31 Jan 2013 20:07:40 +0530
changeset 61
9c1e7ae975db
parent 60
c04f54d5b672
child 62
f7825c1a11d3

8007286: Add JavaAdapter and importPackage to compatibility script
Reviewed-by: lagergren, jlaskey

src/jdk/nashorn/api/scripting/NashornException.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/api/scripting/NashornScriptEngine.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/api/scripting/resources/engine.js file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/parser/TokenLookup.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/parser/TokenType.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/ECMAException.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/PropertyHashMap.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/ScriptObject.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js file | annotate | diff | comparison | revisions
test/script/basic/importpackage.js file | annotate | diff | comparison | revisions
test/script/basic/javaadapter.js file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/api/scripting/NashornException.java	Wed Jan 30 21:15:14 2013 +0530
     1.2 +++ b/src/jdk/nashorn/api/scripting/NashornException.java	Thu Jan 31 20:07:40 2013 +0530
     1.3 @@ -44,6 +44,9 @@
     1.4      // script column number
     1.5      private int         column;
     1.6  
     1.7 +    // script source name used for "engine.js"
     1.8 +    protected static final String ENGINE_SCRIPT_SOURCE_NAME = "nashorn:engine/resources/engine.js";
     1.9 +
    1.10      /**
    1.11       * Constructor
    1.12       *
     2.1 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Wed Jan 30 21:15:14 2013 +0530
     2.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Thu Jan 31 20:07:40 2013 +0530
     2.3 @@ -242,41 +242,6 @@
     2.4          return UNDEFINED;
     2.5      }
     2.6  
     2.7 -    /**
     2.8 -     * This hook is used to call js global functions exposed from Java code.
     2.9 -     *
    2.10 -     * @param self 'this' passed from the script
    2.11 -     * @param ctxt current ScriptContext in which method is searched
    2.12 -     * @param name name of the method
    2.13 -     * @param args arguments to be passed to the method
    2.14 -     * @return return value of the called method
    2.15 -     */
    2.16 -    public Object __noSuchMethod__(final Object self, final ScriptContext ctxt, final String name, final Object args) {
    2.17 -        final int scope = ctxt.getAttributesScope(name);
    2.18 -        final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
    2.19 -        Object value;
    2.20 -
    2.21 -        if (scope != -1) {
    2.22 -            value = ctxt.getAttribute(name, scope);
    2.23 -        } else {
    2.24 -            if (self == UNDEFINED) {
    2.25 -                referenceError(ctxtGlobal, "not.defined", name);
    2.26 -            } else {
    2.27 -                typeError(ctxtGlobal, "no.such.function", name, ScriptRuntime.safeToString(ctxtGlobal));
    2.28 -            }
    2.29 -            return UNDEFINED;
    2.30 -        }
    2.31 -
    2.32 -        value = ScriptObjectMirror.unwrap(value, ctxtGlobal);
    2.33 -        if (value instanceof ScriptFunction) {
    2.34 -            return ScriptObjectMirror.unwrap(ScriptRuntime.apply((ScriptFunction)value, ctxtGlobal, args), ctxtGlobal);
    2.35 -        }
    2.36 -
    2.37 -        typeError(ctxtGlobal, "not.a.function", ScriptRuntime.safeToString(name));
    2.38 -
    2.39 -        return UNDEFINED;
    2.40 -    }
    2.41 -
    2.42      private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) {
    2.43          final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
    2.44          if (bindings instanceof ScriptObjectMirror) {
    2.45 @@ -320,10 +285,10 @@
    2.46      }
    2.47  
    2.48      private void evalEngineScript() throws ScriptException {
    2.49 -        evalSupportScript("resources/engine.js");
    2.50 +        evalSupportScript("resources/engine.js", NashornException.ENGINE_SCRIPT_SOURCE_NAME);
    2.51      }
    2.52  
    2.53 -    private void evalSupportScript(final String script) throws ScriptException {
    2.54 +    private void evalSupportScript(final String script, final String name) throws ScriptException {
    2.55          try {
    2.56              final InputStream is = AccessController.doPrivileged(
    2.57                      new PrivilegedExceptionAction<InputStream>() {
    2.58 @@ -333,7 +298,7 @@
    2.59                              return url.openStream();
    2.60                          }
    2.61                      });
    2.62 -            put(ScriptEngine.FILENAME, "<engine>:" + script);
    2.63 +            put(ScriptEngine.FILENAME, name);
    2.64              try (final InputStreamReader isr = new InputStreamReader(is)) {
    2.65                  eval(isr);
    2.66              }
    2.67 @@ -427,7 +392,7 @@
    2.68              // NOTE: FIXME: If this is jrunscript's init.js, we want to run the replacement.
    2.69              // This should go away once we fix jrunscript's copy of init.js.
    2.70              if ("<system-init>".equals(fileName)) {
    2.71 -                evalSupportScript("resources/init.js");
    2.72 +                evalSupportScript("resources/init.js", "nashorn:engine/resources/init.js");
    2.73                  return null;
    2.74              }
    2.75  
     3.1 --- a/src/jdk/nashorn/api/scripting/resources/engine.js	Wed Jan 30 21:15:14 2013 +0530
     3.2 +++ b/src/jdk/nashorn/api/scripting/resources/engine.js	Thu Jan 31 20:07:40 2013 +0530
     3.3 @@ -39,16 +39,6 @@
     3.4      }
     3.5  });
     3.6  
     3.7 -Object.defineProperty(this, "__noSuchMethod__", {
     3.8 -    configurable: true,
     3.9 -    enumerable: false,
    3.10 -    writable: true,
    3.11 -    value: function (name, args) {
    3.12 -        'use strict';
    3.13 -        return engine.__noSuchMethod__(this, context, name, args);
    3.14 -    }
    3.15 -});
    3.16 -
    3.17  function print(str) {
    3.18      var writer = context.getWriter();
    3.19      if (! (writer instanceof java.io.PrintWriter)) {
     4.1 --- a/src/jdk/nashorn/internal/parser/TokenLookup.java	Wed Jan 30 21:15:14 2013 +0530
     4.2 +++ b/src/jdk/nashorn/internal/parser/TokenLookup.java	Thu Jan 31 20:07:40 2013 +0530
     4.3 @@ -32,7 +32,7 @@
     4.4   * Fast lookup of operators and keywords.
     4.5   *
     4.6   */
     4.7 -public class TokenLookup {
     4.8 +public final class TokenLookup {
     4.9      /**
    4.10       * Lookup table for tokens.
    4.11       */
     5.1 --- a/src/jdk/nashorn/internal/parser/TokenType.java	Wed Jan 30 21:15:14 2013 +0530
     5.2 +++ b/src/jdk/nashorn/internal/parser/TokenType.java	Thu Jan 31 20:07:40 2013 +0530
     5.3 @@ -275,7 +275,7 @@
     5.4          return name != null && name.length() > 0 && name.charAt(0) == c;
     5.5      }
     5.6  
     5.7 -    public static TokenType[] getValues() {
     5.8 +    static TokenType[] getValues() {
     5.9         return values;
    5.10      }
    5.11  
     6.1 --- a/src/jdk/nashorn/internal/runtime/ECMAException.java	Wed Jan 30 21:15:14 2013 +0530
     6.2 +++ b/src/jdk/nashorn/internal/runtime/ECMAException.java	Thu Jan 31 20:07:40 2013 +0530
     6.3 @@ -58,15 +58,9 @@
     6.4  
     6.5      /** We assume that compiler generates script classes into the known package. */
     6.6      private static final String scriptPackage;
     6.7 -
     6.8 -    /** Package (internal) name where Nashorn script engine implementation lives */
     6.9 -    private static final String enginePackageInternal;
    6.10 -
    6.11      static {
    6.12          String name = JS$.class.getName();
    6.13          scriptPackage = name.substring(0, name.lastIndexOf('.'));
    6.14 -        name = NashornScriptEngine.class.getName();
    6.15 -        enginePackageInternal = name.substring(0, name.lastIndexOf('.')).replace(".", "/");
    6.16      }
    6.17  
    6.18      /** Object thrown. */
    6.19 @@ -168,7 +162,7 @@
    6.20               * also, we don't want to report JavaScript code that lives in script engine implementation
    6.21               * We want to report only user's own scripts and not any of our own scripts like "engine.js"
    6.22               */
    6.23 -            return source != null && !source.endsWith(".java") && !source.contains(enginePackageInternal);
    6.24 +            return source != null && !source.endsWith(".java") && !source.contains(ENGINE_SCRIPT_SOURCE_NAME);
    6.25          }
    6.26          return false;
    6.27      }
     7.1 --- a/src/jdk/nashorn/internal/runtime/PropertyHashMap.java	Wed Jan 30 21:15:14 2013 +0530
     7.2 +++ b/src/jdk/nashorn/internal/runtime/PropertyHashMap.java	Thu Jan 31 20:07:40 2013 +0530
     7.3 @@ -268,7 +268,7 @@
     7.4       *
     7.5       * @return Array of all properties.
     7.6       */
     7.7 -    public Property[] getProperties() {
     7.8 +    Property[] getProperties() {
     7.9          if (properties == null) {
    7.10              final Property[] array = new Property[size];
    7.11              int i = size;
     8.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Wed Jan 30 21:15:14 2013 +0530
     8.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Jan 31 20:07:40 2013 +0530
     8.3 @@ -1937,11 +1937,7 @@
     8.4          final boolean      scopeCall = isScope() && NashornCallSiteDescriptor.isScope(desc);
     8.5  
     8.6          if (find == null) {
     8.7 -            if (scopeCall) {
     8.8 -                ECMAErrors.referenceError("not.defined", name);
     8.9 -                throw new AssertionError(); // never reached
    8.10 -            }
    8.11 -            return createEmptyGetter(desc, name);
    8.12 +            return noSuchProperty(desc, request);
    8.13          }
    8.14  
    8.15          final ScriptFunction func = (ScriptFunction)getObjectValue(find);
    8.16 @@ -3335,10 +3331,10 @@
    8.17      }
    8.18  
    8.19      /** This is updated only in debug mode - counts number of {@code ScriptObject} instances created */
    8.20 -    protected static int count;
    8.21 +    private static int count;
    8.22  
    8.23      /** This is updated only in debug mode - counts number of {@code ScriptObject} instances created that are scope */
    8.24 -    protected static int scopeCount;
    8.25 +    private static int scopeCount;
    8.26  
    8.27      /**
    8.28       * Get number of {@code ScriptObject} instances created. If not running in debug
     9.1 --- a/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js	Wed Jan 30 21:15:14 2013 +0530
     9.2 +++ b/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js	Thu Jan 31 20:07:40 2013 +0530
     9.3 @@ -27,6 +27,56 @@
     9.4   * often used functionality is supported.
     9.5   */
     9.6  
     9.7 +// JavaAdapter
     9.8 +Object.defineProperty(this, "JavaAdapter", {
     9.9 +    configurable: true, enumerable: false, writable: true,
    9.10 +    value: function() {
    9.11 +        if (arguments.length < 2) {
    9.12 +            throw new TypeError("JavaAdapter requires atleast two arguments");
    9.13 +        }
    9.14 +            
    9.15 +        var types = Array.prototype.slice.call(arguments, 0, arguments.length - 1);
    9.16 +        var NewType = Java.extend.apply(Java, types);
    9.17 +        return new NewType(arguments[arguments.length - 1]);
    9.18 +    }
    9.19 +});
    9.20 +
    9.21 +// importPackage
    9.22 +Object.defineProperty(this, "importPackage", {
    9.23 +    configurable: true, enumerable: false, writable: true,
    9.24 +    value: (function() {
    9.25 +        var _packages = [];
    9.26 +        var global = this;
    9.27 +        var oldNoSuchProperty = global.__noSuchProperty__;
    9.28 +        global.__noSuchProperty__ = function(name) {
    9.29 +            for (var i in _packages) {
    9.30 +                try {
    9.31 +                    var type = Java.type(_packages[i] + "." + name);
    9.32 +                    global[name] = type;
    9.33 +                    return type;
    9.34 +                } catch (e) {}
    9.35 +            }
    9.36 +            
    9.37 +            return oldNoSuchProperty? oldNoSuchProperty(name) : undefined;
    9.38 +        }
    9.39 +        
    9.40 +        var prefix = "[JavaPackage ";
    9.41 +        return function() {
    9.42 +            for (var i in arguments) {
    9.43 +                var pkgName = arguments[i];
    9.44 +                if ((typeof pkgName) != 'string') {
    9.45 +                    pkgName = String(pkgName);
    9.46 +                    // extract name from JavaPackage object
    9.47 +                    if (pkgName.startsWith(prefix)) {
    9.48 +                        pkgName = pkgName.substring(prefix.length, pkgName.length - 1);
    9.49 +                    }
    9.50 +                }
    9.51 +                _packages.push(pkgName);
    9.52 +            }
    9.53 +        }
    9.54 +    })()
    9.55 +});
    9.56 +
    9.57  // Object.prototype.__defineGetter__
    9.58  Object.defineProperty(Object.prototype, "__defineGetter__", {
    9.59      configurable: true, enumerable: false, writable: true,
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/test/script/basic/importpackage.js	Thu Jan 31 20:07:40 2013 +0530
    10.3 @@ -0,0 +1,59 @@
    10.4 +/*
    10.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.7 + * 
    10.8 + * This code is free software; you can redistribute it and/or modify it
    10.9 + * under the terms of the GNU General Public License version 2 only, as
   10.10 + * published by the Free Software Foundation.
   10.11 + * 
   10.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   10.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   10.15 + * version 2 for more details (a copy is included in the LICENSE file that
   10.16 + * accompanied this code).
   10.17 + * 
   10.18 + * You should have received a copy of the GNU General Public License version
   10.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   10.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   10.21 + * 
   10.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   10.23 + * or visit www.oracle.com if you need additional information or have any
   10.24 + * questions.
   10.25 + */
   10.26 +
   10.27 +/**
   10.28 + * Test to check importPackage function.
   10.29 + *
   10.30 + * @test
   10.31 + * @run
   10.32 + */
   10.33 +
   10.34 +try {
   10.35 +    load("nashorn:mozilla_compat.js");
   10.36 +} catch (e) {
   10.37 +}
   10.38 +
   10.39 +importPackage(java.util);
   10.40 +
   10.41 +var m = new HashMap();
   10.42 +if (!(m instanceof java.util.HashMap)) {
   10.43 +    fail("expected 'm' to be a java.util.HashMap instance");
   10.44 +}
   10.45 +
   10.46 +function checkJavaClass(cls) {
   10.47 +    if (! Java.isType(cls)) {
   10.48 +        fail(cls + " is not a Java class");
   10.49 +    }
   10.50 +}
   10.51 +
   10.52 +importPackage(java.lang.reflect, javax.script);
   10.53 +checkJavaClass(Method);
   10.54 +checkJavaClass(Field);
   10.55 +checkJavaClass(Constructor);
   10.56 +checkJavaClass(ScriptContext);
   10.57 +checkJavaClass(ScriptEngine);
   10.58 +
   10.59 +var bindings = new SimpleBindings();
   10.60 +if (!(bindings instanceof javax.script.SimpleBindings)) {
   10.61 +    fail("expected 'bindings' to be a javax.script.SimpleBindings instance");
   10.62 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/script/basic/javaadapter.js	Thu Jan 31 20:07:40 2013 +0530
    11.3 @@ -0,0 +1,119 @@
    11.4 +/*
    11.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + * 
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.
   11.11 + * 
   11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.15 + * version 2 for more details (a copy is included in the LICENSE file that
   11.16 + * accompanied this code).
   11.17 + * 
   11.18 + * You should have received a copy of the GNU General Public License version
   11.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.21 + * 
   11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.23 + * or visit www.oracle.com if you need additional information or have any
   11.24 + * questions.
   11.25 + */
   11.26 +
   11.27 +/**
   11.28 + * Test to check JavaAdapter constructor.
   11.29 + *
   11.30 + * @test
   11.31 + * @run
   11.32 + */
   11.33 +
   11.34 +try {
   11.35 +    load("nashorn:mozilla_compat.js");
   11.36 +} catch (e) {
   11.37 +}
   11.38 +
   11.39 +// try various JavaAdapter cases
   11.40 +
   11.41 +// Single interface
   11.42 +var runReached = false;
   11.43 +var r = new JavaAdapter(java.lang.Runnable) {
   11.44 +    run: function() {
   11.45 +        runReached = true;
   11.46 +    }
   11.47 +};
   11.48 +
   11.49 +r.run();
   11.50 +if (! runReached) {
   11.51 +    fail("run was not called");
   11.52 +}
   11.53 +
   11.54 +if (! (r instanceof java.lang.Runnable)) {
   11.55 +    fail("r is not a Runnable");
   11.56 +}
   11.57 +
   11.58 +// Multiple intefaces
   11.59 +var runReached = false;
   11.60 +var actionPerformedReached = false;
   11.61 +
   11.62 +var obj = new JavaAdapter(java.awt.event.ActionListener, java.lang.Runnable) {
   11.63 +    actionPerformed : function(e) {
   11.64 +        actionPerformedReached = true;
   11.65 +    },
   11.66 +
   11.67 +    run: function() {
   11.68 +        runReached = true;
   11.69 +    }
   11.70 +};
   11.71 +
   11.72 +obj.actionPerformed(null);
   11.73 +if (! actionPerformedReached) {
   11.74 +    fail("actionPerformed was not called");
   11.75 +}
   11.76 +
   11.77 +obj.run();
   11.78 +if (! runReached) {
   11.79 +    fail("run was not called");
   11.80 +}
   11.81 +
   11.82 +if (! (obj instanceof java.lang.Runnable)) {
   11.83 +    fail("obj is not a Runnable");
   11.84 +}
   11.85 +
   11.86 +if (! (obj instanceof java.awt.event.ActionListener)) {
   11.87 +    fail("obj is not an ActionListener");
   11.88 +}
   11.89 +
   11.90 +// Single class
   11.91 +var obj = new JavaAdapter(java.lang.Object) {
   11.92 +    toString: function() { return "I am an Object"; }
   11.93 +};
   11.94 +
   11.95 +if (! (obj instanceof java.lang.Object)) {
   11.96 +    fail("obj is not an instance of java.lang.Object");
   11.97 +}
   11.98 +
   11.99 +if (obj.toString() != "I am an Object") {
  11.100 +    fail("Object.toString did not get called");
  11.101 +}
  11.102 +
  11.103 +// Single class and single interface
  11.104 +var runReached = false;
  11.105 +var obj = new JavaAdapter(java.lang.Object, java.lang.Runnable) {
  11.106 +    run: function() {
  11.107 +        runReached = true;
  11.108 +    },
  11.109 +
  11.110 +    hashCode: function() {
  11.111 +        return 12;
  11.112 +    }
  11.113 +};
  11.114 +
  11.115 +obj.run();
  11.116 +if (! runReached) {
  11.117 +    fail("run was not called");
  11.118 +}
  11.119 +
  11.120 +if (obj.hashCode() != 12) {
  11.121 +    fail("hashCode does not return 12");
  11.122 +}

mercurial