Mercurial > hg > jdk9-shenandoah > nashorn
view src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java @ 1384:5beae9dfcdb9
8133948: Add 'edit' function to allow external editing of scripts
Reviewed-by: attila, hannesw, jlahoda
author | sundar |
---|---|
date | Fri, 21 Aug 2015 18:01:23 +0530 |
parents | 5b0c3dc04a73 |
children | a5a67511b22b |
line wrap: on
line source
/* * 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.File; import java.io.InputStream; import java.io.InputStreamReader; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; 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.runtime.Context; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.ScriptEnvironment; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.tools.Shell; /** * Interactive command line Shell for Nashorn. */ public final class Main extends Shell { private Main() {} // file where history is persisted. private static final File HIST_FILE = new File(new File(System.getProperty("user.home")), ".jjs.history"); /** * 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); final Completer completer = new NashornCompleter(context, global, this); try (final Console in = new Console(System.in, System.out, HIST_FILE, completer)) { if (globalChanged) { Context.setGlobal(global); } global.addShellBuiltins(); if (System.getSecurityManager() == null) { // expose history object for reflecting on command line history global.addOwnProperty("history", Property.NOT_ENUMERABLE, new HistoryObject(in.getHistory())); // 'edit' command global.addOwnProperty("edit", Property.NOT_ENUMERABLE, new EditObject(err::println, str -> { // could be called from different thread (GUI), we need to handle Context set/reset final Global _oldGlobal = Context.getGlobal(); final boolean _globalChanged = (oldGlobal != global); if (_globalChanged) { Context.setGlobal(global); } try { evalImpl(context, global, str, err, env._dump_on_error); } finally { if (_globalChanged) { Context.setGlobal(_oldGlobal); } } }, in)); } 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; } evalImpl(context, global, source, err, env._dump_on_error); } } catch (final Exception e) { err.println(e); if (env._dump_on_error) { e.printStackTrace(err); } } finally { if (globalChanged) { Context.setGlobal(oldGlobal); } } return SUCCESS; } private void evalImpl(final Context context, final Global global, final String source, final PrintWriter err, final boolean doe) { try { final Object res = context.eval(global, source, global, "<shell>"); if (res != ScriptRuntime.UNDEFINED) { err.println(JSType.toString(res)); } } catch (final Exception e) { err.println(e); if (doe) { e.printStackTrace(err); } } } }