mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-10 10:28:37 +00:00
8145486: jjs should support documentation key shortcut in interactive mode
Reviewed-by: mhaupt, hannesw
This commit is contained in:
parent
d8b6306e43
commit
2cee75db22
@ -59,6 +59,8 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_C
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SETTER_PREFIX;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_OBJECT;
|
||||
@ -291,6 +293,13 @@ public class ClassGenerator {
|
||||
mi.push(memInfo.getArity());
|
||||
mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY, SCRIPTFUNCTION_SETARITY_DESC);
|
||||
}
|
||||
|
||||
String doc = memInfo.getDocumentation();
|
||||
if (doc != null) {
|
||||
mi.dup();
|
||||
mi.loadLiteral(memInfo.getDocumentation());
|
||||
mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATION, SCRIPTFUNCTION_SETDOCUMENTATION_DESC);
|
||||
}
|
||||
}
|
||||
|
||||
static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) {
|
||||
|
||||
@ -42,6 +42,8 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_I
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC4;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATION_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE_DESC;
|
||||
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
|
||||
@ -159,6 +161,13 @@ public class ConstructorGenerator extends ClassGenerator {
|
||||
mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY,
|
||||
SCRIPTFUNCTION_SETARITY_DESC);
|
||||
}
|
||||
final String doc = constructor.getDocumentation();
|
||||
if (doc != null) {
|
||||
mi.loadThis();
|
||||
mi.loadLiteral(doc);
|
||||
mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATION,
|
||||
SCRIPTFUNCTION_SETDOCUMENTATION_DESC);
|
||||
}
|
||||
}
|
||||
mi.returnVoid();
|
||||
mi.computeMaxs();
|
||||
|
||||
@ -85,6 +85,8 @@ public final class MemberInfo implements Cloneable {
|
||||
private MemberInfo.Kind kind;
|
||||
// script property name
|
||||
private String name;
|
||||
// documentation for this member
|
||||
private String documentation;
|
||||
// script property attributes
|
||||
private int attributes;
|
||||
// name of the java member
|
||||
@ -136,6 +138,20 @@ public final class MemberInfo implements Cloneable {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the documentation
|
||||
*/
|
||||
public String getDocumentation() {
|
||||
return documentation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param doc the documentation to set
|
||||
*/
|
||||
public void setDocumentation(final String doc) {
|
||||
this.documentation = doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag something as specialized constructor or not
|
||||
* @param isSpecializedConstructor boolean, true if specialized constructor
|
||||
|
||||
@ -206,6 +206,7 @@ public class ScriptClassInfoCollector extends ClassVisitor {
|
||||
// These could be "null" if values are not supplied,
|
||||
// in which case we have to use the default values.
|
||||
private String name;
|
||||
private String documentation;
|
||||
private Integer attributes;
|
||||
private Integer arity;
|
||||
private Where where;
|
||||
@ -221,6 +222,13 @@ public class ScriptClassInfoCollector extends ClassVisitor {
|
||||
if (name.isEmpty()) {
|
||||
name = null;
|
||||
}
|
||||
break;
|
||||
case "documentation":
|
||||
this.documentation = (String)annotationValue;
|
||||
if (documentation.isEmpty()) {
|
||||
documentation = null;
|
||||
}
|
||||
|
||||
break;
|
||||
case "attributes":
|
||||
this.attributes = (Integer)annotationValue;
|
||||
@ -270,6 +278,8 @@ public class ScriptClassInfoCollector extends ClassVisitor {
|
||||
} else {
|
||||
memInfo.setName(name == null ? methodName : name);
|
||||
}
|
||||
|
||||
memInfo.setDocumentation(documentation);
|
||||
memInfo.setAttributes(attributes == null ? MemberInfo.DEFAULT_ATTRIBUTES : attributes);
|
||||
|
||||
memInfo.setArity((arity == null)? MemberInfo.DEFAULT_ARITY : arity);
|
||||
|
||||
@ -118,6 +118,8 @@ public interface StringConstants {
|
||||
static final String SCRIPTFUNCTION_TYPE = TYPE_SCRIPTFUNCTION.getInternalName();
|
||||
static final String SCRIPTFUNCTION_SETARITY = "setArity";
|
||||
static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
|
||||
static final String SCRIPTFUNCTION_SETDOCUMENTATION = "setDocumentation";
|
||||
static final String SCRIPTFUNCTION_SETDOCUMENTATION_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING);
|
||||
static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype";
|
||||
static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT);
|
||||
static final String SCRIPTFUNCTION_CREATEBUILTIN = "createBuiltin";
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
package jdk.nashorn.tools.jjs;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -34,21 +35,24 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import jdk.internal.jline.NoInterruptUnixTerminal;
|
||||
import jdk.internal.jline.Terminal;
|
||||
import jdk.internal.jline.TerminalFactory;
|
||||
import jdk.internal.jline.TerminalFactory.Flavor;
|
||||
import jdk.internal.jline.WindowsTerminal;
|
||||
import jdk.internal.jline.console.ConsoleReader;
|
||||
import jdk.internal.jline.console.KeyMap;
|
||||
import jdk.internal.jline.console.completer.Completer;
|
||||
import jdk.internal.jline.console.history.FileHistory;
|
||||
|
||||
class Console implements AutoCloseable {
|
||||
private static final String DOCUMENTATION_SHORTCUT = "\033\133\132"; //Shift-TAB
|
||||
private final ConsoleReader in;
|
||||
private final FileHistory history;
|
||||
|
||||
Console(final InputStream cmdin, final PrintStream cmdout, final File historyFile,
|
||||
final Completer completer) throws IOException {
|
||||
final Completer completer, final Function<String, String> docHelper) throws IOException {
|
||||
TerminalFactory.registerFlavor(Flavor.WINDOWS, isCygwin()? JJSUnixTerminal::new : JJSWindowsTerminal::new);
|
||||
TerminalFactory.registerFlavor(Flavor.UNIX, JJSUnixTerminal::new);
|
||||
in = new ConsoleReader(cmdin, cmdout);
|
||||
@ -58,6 +62,7 @@ class Console implements AutoCloseable {
|
||||
in.setHistory(history = new FileHistory(historyFile));
|
||||
in.addCompleter(completer);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread((Runnable)this::saveHistory));
|
||||
bind(DOCUMENTATION_SHORTCUT, (ActionListener)evt -> showDocumentation(docHelper));
|
||||
}
|
||||
|
||||
String readLine(final String prompt) throws IOException {
|
||||
@ -138,4 +143,34 @@ class Console implements AutoCloseable {
|
||||
private static boolean isCygwin() {
|
||||
return System.getenv("SHELL") != null;
|
||||
}
|
||||
|
||||
private void bind(String shortcut, Object action) {
|
||||
KeyMap km = in.getKeys();
|
||||
for (int i = 0; i < shortcut.length(); i++) {
|
||||
final Object value = km.getBound(Character.toString(shortcut.charAt(i)));
|
||||
if (value instanceof KeyMap) {
|
||||
km = (KeyMap) value;
|
||||
} else {
|
||||
km.bind(shortcut.substring(i), action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showDocumentation(final Function<String, String> docHelper) {
|
||||
final String buffer = in.getCursorBuffer().buffer.toString();
|
||||
final int cursor = in.getCursorBuffer().cursor;
|
||||
final String doc = docHelper.apply(buffer.substring(0, cursor));
|
||||
try {
|
||||
if (doc != null) {
|
||||
in.println();
|
||||
in.println(doc);
|
||||
in.redrawLine();
|
||||
in.flush();
|
||||
} else {
|
||||
in.beep();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
|
||||
package jdk.nashorn.tools.jjs;
|
||||
|
||||
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
@ -33,15 +36,21 @@ import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import jdk.internal.jline.console.completer.Completer;
|
||||
import jdk.internal.jline.console.UserInterruptException;
|
||||
import jdk.nashorn.api.scripting.NashornException;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.objects.NativeJava;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.NativeJavaPackage;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.Property;
|
||||
import jdk.nashorn.internal.runtime.ScriptEnvironment;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
import jdk.nashorn.tools.Shell;
|
||||
|
||||
@ -109,7 +118,32 @@ public final class Main extends Shell {
|
||||
final PropertiesHelper propsHelper = new PropertiesHelper(env._classpath);
|
||||
final NashornCompleter completer = new NashornCompleter(context, global, this, propsHelper);
|
||||
|
||||
try (final Console in = new Console(System.in, System.out, HIST_FILE, completer)) {
|
||||
try (final Console in = new Console(System.in, System.out, HIST_FILE, completer,
|
||||
str -> {
|
||||
try {
|
||||
final Object res = context.eval(global, str, global, "<shell>");
|
||||
if (res != null && res != UNDEFINED) {
|
||||
// Special case Java types: show the javadoc for the class.
|
||||
if (NativeJava.isType(UNDEFINED, res)) {
|
||||
final String typeName = NativeJava.typeName(UNDEFINED, res).toString();
|
||||
final String url = typeName.replace('.', '/').replace('$', '.') + ".html";
|
||||
openBrowserForJavadoc(url);
|
||||
} else if (res instanceof NativeJavaPackage) {
|
||||
final String pkgName = ((NativeJavaPackage)res).getName();
|
||||
final String url = pkgName.replace('.', '/') + "/package-summary.html";
|
||||
openBrowserForJavadoc(url);
|
||||
} else if (res instanceof ScriptFunction) {
|
||||
return ((ScriptFunction)res).getDocumentation();
|
||||
}
|
||||
|
||||
// FIXME: better than toString for other cases?
|
||||
return JSType.toString(res);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return null;
|
||||
})) {
|
||||
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(global);
|
||||
}
|
||||
@ -164,7 +198,7 @@ public final class Main extends Shell {
|
||||
|
||||
try {
|
||||
final Object res = context.eval(global, source, global, "<shell>");
|
||||
if (res != ScriptRuntime.UNDEFINED) {
|
||||
if (res != UNDEFINED) {
|
||||
err.println(toString(res, global));
|
||||
}
|
||||
} catch (final Exception exp) {
|
||||
@ -218,7 +252,7 @@ public final class Main extends Shell {
|
||||
final PrintWriter err, final boolean doe) {
|
||||
try {
|
||||
final Object res = context.eval(global, source, global, "<shell>");
|
||||
if (res != ScriptRuntime.UNDEFINED) {
|
||||
if (res != UNDEFINED) {
|
||||
err.println(JSType.toString(res));
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
@ -228,4 +262,15 @@ public final class Main extends Shell {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: needs to be changed to use javase 9 docs later
|
||||
private static String JAVADOC_BASE = "http://download.java.net/jdk9/docs/api/";
|
||||
|
||||
private static void openBrowserForJavadoc(String relativeUrl) {
|
||||
try {
|
||||
final URI uri = new URI(JAVADOC_BASE + relativeUrl);
|
||||
Desktop.getDesktop().browse(uri);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +148,8 @@ public final class NativeObject {
|
||||
* @param buf external buffer - should be a nio ByteBuffer
|
||||
* @return the 'obj' object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "sets ByteBuffer to hold indexed data (nashorn extension)")
|
||||
public static ScriptObject setIndexedPropertiesToExternalArrayData(final Object self, final Object obj, final Object buf) {
|
||||
Global.checkObject(obj);
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
@ -168,7 +169,8 @@ public final class NativeObject {
|
||||
* @param obj object to get prototype from
|
||||
* @return the prototype of an object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "returns the prototype of the specified object")
|
||||
public static Object getPrototypeOf(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).getProto();
|
||||
@ -195,7 +197,8 @@ public final class NativeObject {
|
||||
* @param proto prototype object to be used
|
||||
* @return object whose prototype is set
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "sets the prototype of the given object (ES6)")
|
||||
public static Object setPrototypeOf(final Object self, final Object obj, final Object proto) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
((ScriptObject)obj).setPrototypeOf(proto);
|
||||
@ -216,7 +219,8 @@ public final class NativeObject {
|
||||
* @param prop property descriptor
|
||||
* @return property descriptor
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "returns a property descriptor for an own property (not inherited property)")
|
||||
public static Object getOwnPropertyDescriptor(final Object self, final Object obj, final Object prop) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
final String key = JSType.toString(prop);
|
||||
@ -240,7 +244,8 @@ public final class NativeObject {
|
||||
* @param obj object to query for property names
|
||||
* @return array of property names
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "returns an array of all properties (enumerable or not) found directly on the given object")
|
||||
public static ScriptObject getOwnPropertyNames(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return new NativeArray(((ScriptObject)obj).getOwnKeys(true));
|
||||
@ -258,7 +263,8 @@ public final class NativeObject {
|
||||
* @param obj object to query for property names
|
||||
* @return array of property names
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "returns an array of all symbol properties found directly on the given object (ES6)")
|
||||
public static ScriptObject getOwnPropertySymbols(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return new NativeArray(((ScriptObject)obj).getOwnSymbols(true));
|
||||
@ -276,7 +282,8 @@ public final class NativeObject {
|
||||
* @param props properties to define
|
||||
* @return object created
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "creates a new object with the specified prototype object and properties")
|
||||
public static ScriptObject create(final Object self, final Object proto, final Object props) {
|
||||
if (proto != null) {
|
||||
Global.checkObject(proto);
|
||||
@ -302,7 +309,8 @@ public final class NativeObject {
|
||||
* @param attr attributes for property descriptor
|
||||
* @return object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "adds an own property and/or update the attributes of an existing own property of an object")
|
||||
public static ScriptObject defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
|
||||
final ScriptObject sobj = Global.checkObject(obj);
|
||||
sobj.defineOwnProperty(JSType.toPropertyKey(prop), attr, true);
|
||||
@ -317,7 +325,8 @@ public final class NativeObject {
|
||||
* @param props properties
|
||||
* @return object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "defines new or modifies existing properties directly on the given object")
|
||||
public static ScriptObject defineProperties(final Object self, final Object obj, final Object props) {
|
||||
final ScriptObject sobj = Global.checkObject(obj);
|
||||
final Object propsObj = Global.toObject(props);
|
||||
@ -339,7 +348,8 @@ public final class NativeObject {
|
||||
* @param obj object to seal
|
||||
* @return sealed object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "prevents new properties from being added to the given object and marks existing properties as non-configurable")
|
||||
public static Object seal(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).seal();
|
||||
@ -358,7 +368,8 @@ public final class NativeObject {
|
||||
* @param obj object to freeze
|
||||
* @return frozen object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "prevents new properties from being added to the given object and prevents existing properties from being removed or re-configured")
|
||||
public static Object freeze(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).freeze();
|
||||
@ -376,7 +387,8 @@ public final class NativeObject {
|
||||
* @param obj object, for which to set the internal extensible property to false
|
||||
* @return object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "prevents new properties from ever being added to the given object")
|
||||
public static Object preventExtensions(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).preventExtensions();
|
||||
@ -394,7 +406,8 @@ public final class NativeObject {
|
||||
* @param obj check whether an object is sealed
|
||||
* @return true if sealed, false otherwise
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "tells if an object is sealed or not")
|
||||
public static boolean isSealed(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).isSealed();
|
||||
@ -412,7 +425,8 @@ public final class NativeObject {
|
||||
* @param obj check whether an object
|
||||
* @return true if object is frozen, false otherwise
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "tells if an object is fronzen or not")
|
||||
public static boolean isFrozen(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).isFrozen();
|
||||
@ -430,7 +444,8 @@ public final class NativeObject {
|
||||
* @param obj check whether an object is extensible
|
||||
* @return true if object is extensible, false otherwise
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "tells if an object is extensible or not")
|
||||
public static boolean isExtensible(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).isExtensible();
|
||||
@ -448,7 +463,8 @@ public final class NativeObject {
|
||||
* @param obj object from which to extract keys
|
||||
* @return array of keys in object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "returns an array of the given object's own enumerable properties")
|
||||
public static ScriptObject keys(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
@ -471,7 +487,7 @@ public final class NativeObject {
|
||||
* @param value value of object to be instantiated
|
||||
* @return the new NativeObject
|
||||
*/
|
||||
@Constructor
|
||||
@Constructor(documentation = "creates a new script object or converts given value as a script object")
|
||||
public static Object construct(final boolean newObj, final Object self, final Object value) {
|
||||
final JSType type = JSType.ofNoFunction(value);
|
||||
|
||||
@ -505,7 +521,8 @@ public final class NativeObject {
|
||||
* @param self self reference
|
||||
* @return ToString of object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE,
|
||||
documentation = "returns a string representing of this object")
|
||||
public static String toString(final Object self) {
|
||||
return ScriptRuntime.builtinObjectToString(self);
|
||||
}
|
||||
@ -558,7 +575,8 @@ public final class NativeObject {
|
||||
* @param v property to check for
|
||||
* @return true if property exists in object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE,
|
||||
documentation = "tells whether this object has the specified property or not")
|
||||
public static boolean hasOwnProperty(final Object self, final Object v) {
|
||||
// Convert ScriptObjects to primitive with String.class hint
|
||||
// but no need to convert other primitives to string.
|
||||
@ -575,7 +593,8 @@ public final class NativeObject {
|
||||
* @param v v prototype object to check against
|
||||
* @return true if object is prototype of v
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE,
|
||||
documentation = "tests for this object in another object's prototype chain")
|
||||
public static boolean isPrototypeOf(final Object self, final Object v) {
|
||||
if (!(v instanceof ScriptObject)) {
|
||||
return false;
|
||||
@ -601,7 +620,8 @@ public final class NativeObject {
|
||||
* @param v property to check if enumerable
|
||||
* @return true if property is enumerable
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE,
|
||||
documentation = "tells whether the given property is enumerable or not")
|
||||
public static boolean propertyIsEnumerable(final Object self, final Object v) {
|
||||
final String str = JSType.toString(v);
|
||||
final Object obj = Global.toObject(self);
|
||||
@ -676,7 +696,8 @@ public final class NativeObject {
|
||||
* @param source the source object whose properties are bound to the target
|
||||
* @return the target object after property binding
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
|
||||
documentation = "binds the source object's properties to the target object (nashorn extension)")
|
||||
public static Object bindProperties(final Object self, final Object target, final Object source) {
|
||||
// target object has to be a ScriptObject
|
||||
final ScriptObject targetObj = Global.checkObject(target);
|
||||
|
||||
@ -48,4 +48,9 @@ public @interface Constructor {
|
||||
* arity.
|
||||
*/
|
||||
public int arity() default -2;
|
||||
|
||||
/**
|
||||
* @return the documentation string for this constructor.
|
||||
*/
|
||||
public String documentation() default "";
|
||||
}
|
||||
|
||||
@ -60,4 +60,9 @@ public @interface Function {
|
||||
* @return where this function lives.
|
||||
*/
|
||||
public Where where() default Where.PROTOTYPE;
|
||||
|
||||
/**
|
||||
* @return return the documentation string for this function.
|
||||
*/
|
||||
public String documentation() default "";
|
||||
}
|
||||
|
||||
@ -645,6 +645,24 @@ public class ScriptFunction extends ScriptObject {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the documentation for this function
|
||||
*
|
||||
* @return the documentation
|
||||
*/
|
||||
public final String getDocumentation() {
|
||||
return data.getDocumentation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the documentation for this function
|
||||
*
|
||||
* @param doc documentation String for this function
|
||||
*/
|
||||
public final void setDocumentation(final String doc) {
|
||||
data.setDocumentation(doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name for this function
|
||||
*
|
||||
|
||||
@ -70,6 +70,9 @@ public abstract class ScriptFunctionData implements Serializable {
|
||||
// value, the function might still be capable of receiving variable number of arguments, see isVariableArity.
|
||||
private int arity;
|
||||
|
||||
// this may be null, if not available
|
||||
private String documentation;
|
||||
|
||||
/**
|
||||
* A pair of method handles used for generic invoker and constructor. Field is volatile as it can be initialized by
|
||||
* multiple threads concurrently, but we still tolerate a race condition in it as all values stored into it are
|
||||
@ -118,6 +121,10 @@ public abstract class ScriptFunctionData implements Serializable {
|
||||
return arity;
|
||||
}
|
||||
|
||||
final String getDocumentation() {
|
||||
return documentation != null? documentation : toSource();
|
||||
}
|
||||
|
||||
final boolean isVariableArity() {
|
||||
return (flags & IS_VARIABLE_ARITY) != 0;
|
||||
}
|
||||
@ -137,6 +144,15 @@ public abstract class ScriptFunctionData implements Serializable {
|
||||
this.arity = arity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used from nasgen generated code.
|
||||
*
|
||||
* @param doc documentation for this function
|
||||
*/
|
||||
void setDocumentation(final String doc) {
|
||||
this.documentation = doc;
|
||||
}
|
||||
|
||||
CompiledFunction bind(final CompiledFunction originalInv, final ScriptFunction fn, final Object self, final Object[] args) {
|
||||
final MethodHandle boundInvoker = bindInvokeHandle(originalInv.createComposableInvoker(), fn, self, args);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user