# HG changeset patch # User sundar # Date 1439473047 -19800 # Node ID 705d4af0d4d75349bd1ba1f641f516d400e26493 # Parent c25e882cee9622ec75c4e9d60633539a2f0a8809 8133347: Add makefiles support and basic session, persistence history navigation with jline Reviewed-by: erikj, jlahoda, jlaskey diff -r c25e882cee96 -r 705d4af0d4d7 nashorn/make/BuildNashorn.gmk --- a/nashorn/make/BuildNashorn.gmk Wed Jul 05 20:45:01 2017 +0200 +++ b/nashorn/make/BuildNashorn.gmk Thu Aug 13 19:07:27 2015 +0530 @@ -53,7 +53,10 @@ SERVER_JVM := $(SJAVAC_SERVER_JAVA))) # Build nashorn into intermediate directory -$(eval $(call SetupJavaCompilation,BUILD_NASHORN, \ +# Name the compilation setup the same as the module, as is done in the global +# CompileJavaModules.gmk, to make dependency checking with other modules work +# seamlessly. +$(eval $(call SetupJavaCompilation,jdk.scripting.nashorn, \ SETUP := GENERATE_NEWBYTECODE_DEBUG, \ SRC := $(NASHORN_TOPDIR)/src/jdk.scripting.nashorn/share/classes, \ EXCLUDE_FILES := META-INF/MANIFEST.MF, \ @@ -71,7 +74,7 @@ ADD_JAVAC_FLAGS := -Xbootclasspath/p:"$(SUPPORT_OUTPUTDIR)/special_classes/jdk.scripting.nashorn/classes")) # Nasgen needs nashorn classes -$(BUILD_NASGEN): $(BUILD_NASHORN) +$(BUILD_NASGEN): $(jdk.scripting.nashorn) NASHORN_CLASSES_DIR := $(JDK_OUTPUTDIR)/modules/jdk.scripting.nashorn NASGEN_RUN_FILE := $(NASHORN_CLASSES_DIR)/_the.nasgen.run diff -r c25e882cee96 -r 705d4af0d4d7 nashorn/make/build.xml --- a/nashorn/make/build.xml Wed Jul 05 20:45:01 2017 +0200 +++ b/nashorn/make/build.xml Thu Aug 13 19:07:27 2015 +0530 @@ -147,16 +147,16 @@ - + - + - + - - + + ${line.separator} @@ -165,7 +165,14 @@ - + + + + @@ -230,13 +237,14 @@ - - + + diff -r c25e882cee96 -r 705d4af0d4d7 nashorn/make/project.properties --- a/nashorn/make/project.properties Wed Jul 05 20:45:01 2017 +0200 +++ b/nashorn/make/project.properties Thu Aug 13 19:07:27 2015 +0530 @@ -26,6 +26,9 @@ # location of JDK embedded ASM sources jdk.asm.src.dir=../jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm +# location of JDK embedded jline sources +jdk.jline.src.dir=../jdk/src/jdk.internal.le/share/classes + # source and target levels build.compiler=modern javac.source=1.8 @@ -112,7 +115,7 @@ ${build.test.classes.dir}${path.separator}\ ${file.reference.testng.jar} -meta.inf.dir=${src.dir}/META-INF +meta.inf.dir=${nashorn.module.src.dir}/META-INF run.classpath=\ ${build.classes.dir} @@ -266,7 +269,13 @@ ${nashorn.internal.tests.jar}${path.separator}\ ${nashorn.api.tests.jar} -src.dir=src/jdk.scripting.nashorn/share/classes +nashorn.module.src.dir=src/jdk.scripting.nashorn/share/classes +nashorn.shell.module.src.dir=src/jdk.scripting.nashorn.shell/share/classes + +src.dir=${nashorn.module.src.dir}${path.separator}\ + ${nashorn.shell.module.src.dir}${path.separator}\ + ${jdk.jline.src.dir} + test.src.dir=test/src # -Xmx is used for all tests, -Xms only for octane benchmark diff -r c25e882cee96 -r 705d4af0d4d7 nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java Thu Aug 13 19:07:27 2015 +0530 @@ -0,0 +1,103 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package jdk.nashorn.tools.jjs; + +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.prefs.BackingStoreException; +import java.util.prefs.Preferences; +import jdk.internal.jline.console.ConsoleReader; +import jdk.internal.jline.console.history.History.Entry; +import jdk.internal.jline.console.history.MemoryHistory; + +class Console implements AutoCloseable { + private final ConsoleReader in; + private final PersistentHistory history; + + Console(InputStream cmdin, PrintStream cmdout, Preferences prefs) throws IOException { + in = new ConsoleReader(cmdin, cmdout); + in.setExpandEvents(false); + in.setHandleUserInterrupt(true); + in.setHistory(history = new PersistentHistory(prefs)); + Runtime.getRuntime().addShutdownHook(new Thread(()->close())); + } + + String readLine(String prompt) throws IOException { + return in.readLine(prompt); + } + + + @Override + public void close() { + history.save(); + } + + public static class PersistentHistory extends MemoryHistory { + + private final Preferences prefs; + + protected PersistentHistory(Preferences prefs) { + this.prefs = prefs; + load(); + } + + private static final String HISTORY_LINE_PREFIX = "HISTORY_LINE_"; + + public final void load() { + try { + List keys = new ArrayList<>(Arrays.asList(prefs.keys())); + Collections.sort(keys); + for (String key : keys) { + if (!key.startsWith(HISTORY_LINE_PREFIX)) + continue; + CharSequence line = prefs.get(key, ""); + add(line); + } + } catch (BackingStoreException ex) { + throw new IllegalStateException(ex); + } + } + + public void save() { + Iterator entries = iterator(); + if (entries.hasNext()) { + int len = (int) Math.ceil(Math.log10(size()+1)); + String format = HISTORY_LINE_PREFIX + "%0" + len + "d"; + while (entries.hasNext()) { + Entry entry = entries.next(); + prefs.put(String.format(format, entry.index()), entry.value().toString()); + } + } + } + + } +} diff -r c25e882cee96 -r 705d4af0d4d7 nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java Thu Aug 13 19:07:27 2015 +0530 @@ -0,0 +1,150 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package jdk.nashorn.tools.jjs; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.prefs.Preferences; +import jdk.nashorn.internal.objects.Global; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.ErrorManager; +import jdk.nashorn.internal.runtime.JSType; +import jdk.nashorn.internal.runtime.ScriptEnvironment; +import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.tools.Shell; +import jdk.internal.jline.console.UserInterruptException; + +/** + * Interactive command line Shell for Nashorn. + */ +public final class Main extends Shell { + private Main() {} + + static final Preferences PREFS = Preferences.userRoot().node("tool/jjs"); + + /** + * Main entry point with the default input, output and error streams. + * + * @param args The command line arguments + */ + public static void main(final String[] args) { + try { + final int exitCode = main(System.in, System.out, System.err, args); + if (exitCode != SUCCESS) { + System.exit(exitCode); + } + } catch (final IOException e) { + System.err.println(e); //bootstrapping, Context.err may not exist + System.exit(IO_ERROR); + } + } + + /** + * Starting point for executing a {@code Shell}. Starts a shell with the + * given arguments and streams and lets it run until exit. + * + * @param in input stream for Shell + * @param out output stream for Shell + * @param err error stream for Shell + * @param args arguments to Shell + * + * @return exit code + * + * @throws IOException if there's a problem setting up the streams + */ + public static int main(final InputStream in, final OutputStream out, final OutputStream err, final String[] args) throws IOException { + return new Main().run(in, out, err, args); + } + + /** + * read-eval-print loop for Nashorn shell. + * + * @param context the nashorn context + * @param global global scope object to use + * @return return code + */ + protected int readEvalPrint(final Context context, final Global global) { + final ScriptEnvironment env = context.getEnv(); + final String prompt = bundle.getString("shell.prompt"); + final PrintWriter err = context.getErr(); + final Global oldGlobal = Context.getGlobal(); + final boolean globalChanged = (oldGlobal != global); + + try (final Console in = new Console(System.in, System.out, PREFS)) { + if (globalChanged) { + Context.setGlobal(global); + } + + global.addShellBuiltins(); + + while (true) { + String source = ""; + try { + source = in.readLine(prompt); + } catch (final IOException ioe) { + err.println(ioe.toString()); + if (env._dump_on_error) { + ioe.printStackTrace(err); + } + return IO_ERROR; + } catch (final UserInterruptException ex) { + break; + } + + if (source.isEmpty()) { + continue; + } + + try { + final Object res = context.eval(global, source, global, ""); + if (res != ScriptRuntime.UNDEFINED) { + err.println(JSType.toString(res)); + } + } catch (final Exception e) { + err.println(e); + if (env._dump_on_error) { + e.printStackTrace(err); + } + } + } + } catch (final Exception e) { + err.println(e); + if (env._dump_on_error) { + e.printStackTrace(err); + } + } finally { + if (globalChanged) { + Context.setGlobal(oldGlobal); + } + } + + return SUCCESS; + } +} diff -r c25e882cee96 -r 705d4af0d4d7 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java Wed Jul 05 20:45:01 2017 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java Thu Aug 13 19:07:27 2015 +0530 @@ -68,7 +68,7 @@ /** * Shell message bundle. */ - private static final ResourceBundle bundle = ResourceBundle.getBundle(MESSAGE_RESOURCE, Locale.getDefault()); + protected static final ResourceBundle bundle = ResourceBundle.getBundle(MESSAGE_RESOURCE, Locale.getDefault()); /** * Exit code for command line tool - successful @@ -403,7 +403,7 @@ * @param global global scope object to use * @return return code */ - private static int readEvalPrint(final Context context, final Global global) { + protected int readEvalPrint(final Context context, final Global global) { final String prompt = bundle.getString("shell.prompt"); final BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); final PrintWriter err = context.getErr();