# HG changeset patch # User rfield # Date 1464023525 25200 # Node ID 71874886920fa3432b462ca04e8250d11190fd73 # Parent 8bdc63ff6961afa524825ac047b01bb9420ffc32 8157517: jshell tool: allow undoing operations 8157395: jshell tool: allow the position of options on commands to be more flexible 8157393: jshell tool: change /set newmode ... to be consistent with /retain mode Reviewed-by: jlahoda diff -r 8bdc63ff6961 -r 71874886920f langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java Mon May 23 15:07:10 2016 +0100 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java Mon May 23 10:12:05 2016 -0700 @@ -25,8 +25,13 @@ package jdk.internal.jshell.tool; +import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.stream.Stream; +import static java.util.stream.Collectors.toList; /** * Parse command arguments, derived from StreamTokenizer by @@ -49,13 +54,12 @@ private String sval; private boolean isQuoted = false; - ArgTokenizer(String arg) { - this("", arg); - } + private final Map options = new HashMap<>(); + private final List badOptions = new ArrayList<>(); ArgTokenizer(String prefix, String arg) { this.str = arg; - this.prefix = prefix; + this.prefix = prefix + " "; this.length = arg.length(); quoteChar('"'); quoteChar('\''); @@ -65,17 +69,47 @@ whitespaceChars(0xA0, 0xA0); } + /** + * Return the next non-option argument. Encountered options are stored. + * + * @return the token string, or null if there are no more tokens + */ String next() { - nextToken(); + while (true) { + nextToken(); + if (sval != null && !isQuoted() && sval.startsWith("-")) { + foundOption(sval); + } else { + break; + } + } return sval; } + private void foundOption(String opt) { + if (options.containsKey(opt)) { + options.put(opt, true); + return; + } + + List> matches = + options.entrySet() + .stream() + .filter(e -> e.getKey().startsWith(opt)) + .collect(toList()); + if (matches.size() == 1) { + matches.get(0).setValue(true); + } else { + badOptions.add(opt); + } + } + String[] next(String... strings) { return next(Arrays.stream(strings)); } String[] next(Stream stream) { - nextToken(); + next(); if (sval == null) { return null; } @@ -85,6 +119,68 @@ return matches; } + /** + * Set the allowed options. Must be called before any options would be read + * and before calling any of the option functionality below. + */ + void allowedOptions(String... opts) { + for (String opt : opts) { + options.put(opt, false); + } + } + + /** + * Has the specified option been encountered. + * + * @param opt the option to check + * @return true if the option has been encountered + */ + boolean hasOption(String opt) { + Boolean has = options.get(opt); + if (has == null) { + throw new InternalError("hasOption called before allowedOptions or on bad option"); + } + return has; + } + + /** + * Return the number of encountered options + * + * @return the option count + */ + int optionCount() { + return (int) options.entrySet().stream() + .filter(e -> e.getValue()) + .count(); + } + + /** + * Return the bad options encountered. Bad options are those that were not + * listed in the call to allowedOptions(). + * + * @return as space-separated list the bad options encountered, or the empty + * string if none. + */ + String badOptions() { + return String.join(" ", badOptions); + } + + /** + * Consume the remainder of the input. This is useful to sure all options + * have been encountered and to check to unexpected additional non-option + * input. + * + * @return the string-separated concatenation of all remaining non-option + * arguments. + */ + String remainder() { + List rem = new ArrayList<>(); + while (next() != null) { + rem.add(sval); + } + return String.join(" ", rem); + } + String val() { return sval; } @@ -93,13 +189,6 @@ return isQuoted; } - boolean isIdentifier() { - if (isQuoted) { - return false; - } - return sval.codePoints().allMatch(cp -> Character.isJavaIdentifierPart(cp)); - } - String whole() { return prefix + str; } diff -r 8bdc63ff6961 -r 71874886920f langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Mon May 23 15:07:10 2016 +0100 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Mon May 23 10:12:05 2016 -0700 @@ -55,8 +55,11 @@ // For encoding to Properties String private static final String RECORD_SEPARATOR = "\u241E"; - // Current mode - private Mode mode = new Mode("", false); // initial value placeholder during start-up + // Current mode -- initial value is placeholder during start-up + private Mode mode = new Mode(""); + + // Retained current mode -- for checks + private Mode retainedCurrentMode = null; // Mapping of mode name to mode private final Map modeMap = new HashMap<>(); @@ -118,8 +121,8 @@ return new Setter(messageHandler, at).setTruncation(); } - public boolean setNewMode(MessageHandler messageHandler, ArgTokenizer at) { - return new Setter(messageHandler, at).setNewMode(); + public boolean setMode(MessageHandler messageHandler, ArgTokenizer at) { + return new Setter(messageHandler, at).setMode(); } public boolean setPrompt(MessageHandler messageHandler, ArgTokenizer at) { @@ -135,7 +138,7 @@ } public boolean restoreEncodedModes(MessageHandler messageHandler, String encoded) { - return new Setter(messageHandler, new ArgTokenizer("")).restoreEncodedModes(encoded); + return new Setter(messageHandler, new ArgTokenizer("", "")).restoreEncodedModes(encoded); } public void markModesReadOnly() { @@ -167,7 +170,7 @@ final String name; // Display command verification/information - final boolean commandFluff; + boolean commandFluff; // Event cases: class, method, expression, ... final Map> cases; @@ -192,10 +195,9 @@ * @param name * @param commandFluff True if should display command fluff messages */ - Mode(String name, boolean commandFluff) { + Mode(String name) { this.name = name; - this.commandFluff = commandFluff; - cases = new HashMap<>(); + this.cases = new HashMap<>(); add("name", new Setting(ALWAYS, "%1$s")); add("type", new Setting(ALWAYS, "%2$s")); add("value", new Setting(ALWAYS, "%3$s")); @@ -215,20 +217,18 @@ * Set up a copied mode. * * @param name - * @param commandFluff True if should display command fluff messages * @param m Mode to copy, or null for no fresh */ - Mode(String name, boolean commandFluff, Mode m) { + Mode(String name, Mode m) { this.name = name; - this.commandFluff = commandFluff; - cases = new HashMap<>(); - + this.commandFluff = m.commandFluff; + this.prompt = m.prompt; + this.continuationPrompt = m.continuationPrompt; + this.cases = new HashMap<>(); m.cases.entrySet().stream() .forEach(fes -> fes.getValue() .forEach(ing -> add(fes.getKey(), ing))); - this.prompt = m.prompt; - this.continuationPrompt = m.continuationPrompt; } /** @@ -259,6 +259,16 @@ } /** + * Set if this mode displays informative/confirmational messages on + * commands. + * + * @param fluff the value to set + */ + void setCommandFluff(boolean fluff) { + commandFluff = fluff; + } + + /** * Encodes the mode into a String so it can be saved in Preferences. * * @return the string representation @@ -682,36 +692,71 @@ return valid; } - // For /set newmode [-command|-quiet []] - boolean setNewMode() { - String umode = at.next(); - if (umode == null || !at.isIdentifier()) { - errorat("jshell.err.feedback.expected.new.feedback.mode"); - valid = false; + /** + * Set mode. Create, changed, or delete a feedback mode. For @{code /set + * mode [] [-command|-quiet|-delete]}. + * + * @return true if successful + */ + boolean setMode() { + at.allowedOptions("-command", "-quiet", "-delete"); + String umode = nextModeIdentifier(); + Mode om = null; + String omode = at.next(); + if (valid && omode != null) { + om = toMode(omode); } - if (modeMap.containsKey(umode)) { - errorat("jshell.err.feedback.expected.mode.name", umode); + checkOptionsAndRemainingInput(); + boolean commandOption = at.hasOption("-command"); + boolean quietOption = at.hasOption("-quiet"); + boolean deleteOption = at.hasOption("-delete"); + // Only one (or zero) of the options can be used + if (valid && at.optionCount() > 1) { + errorat("jshell.err.conflicting.options"); valid = false; } - String[] fluffOpt = at.next("-command", "-quiet"); - boolean fluff = fluffOpt == null || fluffOpt.length != 1 || "-command".equals(fluffOpt[0]); - if (fluffOpt != null && fluffOpt.length != 1) { - errorat("jshell.err.feedback.command.quiet"); - valid = false; + if (valid) { + Mode m = modeMap.get(umode); + if (m != null && m.readOnly) { + // Cannot make changes to a the built-in modes + errorat("jshell.err.not.valid.with.predefined.mode", m.name); + valid = false; + } else if (deleteOption) { + if (m == null) { + // Cannot delete a mode that does not exist + errorat("jshell.err.mode.unknown", umode); + valid = false; + } else if (mode.name.equals(m.name)) { + // Cannot delete the current mode out from under us + errorat("jshell.err.cannot.delete.current.mode", umode); + valid = false; + } else { + // Remove the mode + modeMap.remove(umode); + } + } else { + if (om != null || m == null) { + // We are copying and existing mode and/or creating a + // brand-new mode -- in either case create from scratch + m = (om != null) + ? new Mode(umode, om) + : new Mode(umode); + modeMap.put(umode, m); + fluffmsg("jshell.msg.feedback.new.mode", m.name); + // Set the current mode by name, in case we just smashed + // the current mode + if (umode.equals(mode.name)) { + mode = modeMap.get(mode.name); + } + } + if (commandOption || quietOption || om == null) { + // set command fluff, if explicit, or wholly new + m.setCommandFluff(!quietOption); + } + } } - Mode om = null; - String omode = at.next(); - if (omode != null) { - om = toMode(omode); - } - if (valid) { - Mode nm = (om != null) - ? new Mode(umode, fluff, om) - : new Mode(umode, fluff); - modeMap.put(umode, nm); - fluffmsg("jshell.msg.feedback.new.mode", nm.name); - } else { - fluffmsg("jshell.msg.see", "/help /set newmode"); + if (!valid) { + fluffmsg("jshell.msg.see", "/help /set mode"); } return valid; } @@ -736,11 +781,9 @@ errorat("jshell.err.not.valid.with.predefined.mode", m.name); valid = false; } - String field = at.next(); - if (field == null || !at.isIdentifier()) { - errorat("jshell.err.feedback.expected.field"); - valid = false; - } + String field = valid + ? toIdentifier(at.next(), "jshell.err.missing.field", "jshell.err.field.name") + : null; String format = valid ? nextFormat() : null; return installFormat(m, field, format, "/help /set format"); } @@ -772,13 +815,15 @@ String retainFeedback() { String umode = at.next(); if (umode != null) { - Mode m = toMode(umode); + toModeIdentifier(umode); + Mode m = valid ? toMode(umode) : null; if (valid && !m.readOnly && !retainedMap.containsKey(m.name)) { errorat("jshell.err.retained.feedback.mode.must.be.retained.or.predefined"); valid = false; } if (valid) { mode = m; + retainedCurrentMode = m; fluffmsg("jshell.msg.feedback.mode", mode.name); } else { fluffmsg("jshell.msg.see", "/help /retain feedback"); @@ -788,14 +833,63 @@ return mode.name; } + /** + * Retain (or delete from retention) a previously set mode. + * + * @return all retained modes encoded into a String + */ String retainMode() { - Mode m = nextMode(); - if (valid && m.readOnly) { - errorat("jshell.err.not.valid.with.predefined.mode", m.name); + at.allowedOptions("-delete"); + String umode = nextModeIdentifier(); + // -delete is the only valid option, fail for anything else + checkOptionsAndRemainingInput(); + boolean deleteOption = at.hasOption("-delete"); + // Lookup the mode + Mode m; + if (!valid) { + m = null; + // Skip this stuff, we have failed already + } else if (deleteOption) { + // If delete, allow for deleting, from retention, a mode that + // has been locally deleted but is retained. + // Also require the full name. + m = modeMap.get(umode); + if (m == null && !retainedMap.containsKey(umode)) { + errorat("jshell.err.mode.unknown", umode); + valid = false; + } + } else { + // For retain do normal lookup and checking + m = toMode(umode); + } + + // Built-in modes cannot be retained or deleted + if (valid && m != null && m.readOnly) { + errorat("jshell.err.not.valid.with.predefined.mode", umode); valid = false; } if (valid) { - retainedMap.put(m.name, m.encode()); + if (deleteOption) { + if (mode.name.equals(umode)) { + // Cannot delete the current mode out from under us + errorat("jshell.err.cannot.delete.current.mode", umode); + valid = false; + } else if (retainedCurrentMode != null && retainedCurrentMode.name.equals(umode)) { + // Cannot delete the retained mode or re-start has error + errorat("jshell.err.cannot.delete.retained.mode", umode); + valid = false; + } else { + // Delete the mode + modeMap.remove(umode); + retainedMap.remove(umode); + } + } else { + // Retain the current encoding + retainedMap.put(m.name, m.encode()); + } + } + if (valid) { + // Join all the retained encodings return String.join(RECORD_SEPARATOR, retainedMap.values()); } else { fluffmsg("jshell.msg.see", "/help /retain mode"); @@ -804,17 +898,24 @@ } boolean restoreEncodedModes(String allEncoded) { - // Iterate over each record in each encoded mode - String[] ms = allEncoded.split(RECORD_SEPARATOR); - Iterator itr = Arrays.asList(ms).iterator(); - while (itr.hasNext()) { - // Reconstruct the encoded mode - Mode m = new Mode(itr); - modeMap.put(m.name, m); - // Continue to retain it a new retains occur - retainedMap.put(m.name, m.encode()); + try { + // Iterate over each record in each encoded mode + String[] ms = allEncoded.split(RECORD_SEPARATOR); + Iterator itr = Arrays.asList(ms).iterator(); + while (itr.hasNext()) { + // Reconstruct the encoded mode + Mode m = new Mode(itr); + modeMap.put(m.name, m); + // Continue to retain it a new retains occur + retainedMap.put(m.name, m.encode()); + } + return true; + } catch (Throwable exc) { + // Catastrophic corruption -- clear map + errorat("jshell.err.retained.mode.failure", exc); + retainedMap.clear(); + return false; } - return true; } // install the format of a field under parsed selectors @@ -844,14 +945,68 @@ return valid; } + void checkOptionsAndRemainingInput() { + if (!valid) { + return; + } + String junk = at.remainder(); + if (!junk.isEmpty()) { + errorat("jshell.err.unexpected.at.end", junk); + valid = false; + } else { + String bad = at.badOptions(); + if (!bad.isEmpty()) { + errorat("jshell.err.unknown.option", bad); + valid = false; + } + } + } + + /** + * Check that the specified string is an identifier (Java identifier). + * If null display the missing error. If it is not an identifier, + * display the error. + * + * @param id the string to check, MUST be the most recently retrieved + * token from 'at'. + * @param missing the resource error to display if null + * @param err the resource error to display if not an identifier + * @return the identifier string, or null if null or not an identifier + */ + String toIdentifier(String id, String missing, String err) { + if (id == null) { + errorat(missing); + valid = false; + return null; + } + if (at.isQuoted() || + !id.codePoints().allMatch(cp -> Character.isJavaIdentifierPart(cp))) { + errorat(err, id); + valid = false; + return null; + } + return id; + } + + String toModeIdentifier(String id) { + return toIdentifier(id, "jshell.err.missing.mode", "jshell.err.mode.name"); + } + + String nextModeIdentifier() { + return toModeIdentifier(at.next()); + } + Mode nextMode() { - String umode = at.next(); + String umode = nextModeIdentifier(); return toMode(umode); } Mode toMode(String umode) { - if (umode == null || !at.isIdentifier()) { - errorat("jshell.err.feedback.expected.mode"); + if (!valid) { + return null; + } + if (umode == null) { + errorat("jshell.err.missing.mode"); valid = false; return null; } diff -r 8bdc63ff6961 -r 71874886920f langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Mon May 23 15:07:10 2016 +0100 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Mon May 23 10:12:05 2016 -0700 @@ -117,8 +117,6 @@ private static final String LINE_SEP = System.getProperty("line.separator"); private static final Pattern LINEBREAK = Pattern.compile("\\R"); - private static final Pattern HISTORY_ALL_START_FILENAME = Pattern.compile( - "((?(-all|-history|-start))(\\z|\\p{javaWhitespace}+))?(?.*)"); private static final String RECORD_SEPARATOR = "\u241E"; private static final String RB_NAME_PREFIX = "jdk.internal.jshell.tool.resources"; private static final String VERSION_RB_NAME = RB_NAME_PREFIX + ".version"; @@ -462,9 +460,19 @@ } private void start(IOContext in, List loadList) { + // If startup hasn't been set by command line, set from retained/default + if (startup == null) { + startup = prefs.get(STARTUP_KEY, null); + if (startup == null) { + startup = DEFAULT_STARTUP; + } + } + // Read retained editor setting (if any) - String editorString = prefs.get(EDITOR_KEY, null); - if (editorString != null) { + String editorString = prefs.get(EDITOR_KEY, ""); + if (editorString == null || editorString.isEmpty()) { + editor = null; + } else { editor = editorString.split(RECORD_SEPARATOR); } @@ -648,18 +656,10 @@ state.addToClasspath(cmdlineClasspath); } - String start; - if (startup == null) { - start = startup = prefs.get(STARTUP_KEY, null); - if (start == null) { - start = DEFAULT_STARTUP; - } - } else { - start = startup; - } - startUpRun(start); + startUpRun(startup); currentNameSpace = mainNamespace; } + //where -- one-time per run initialization of feedback modes private void initFeedback() { // No fluff, no prefix, for init failures @@ -670,12 +670,15 @@ feedback.markModesReadOnly(); // Restore user defined modes retained on previous run with /retain mode String encoded = prefs.get(MODE_KEY, null); - if (encoded != null) { - feedback.restoreEncodedModes(initmh, encoded); + if (encoded != null && !encoded.isEmpty()) { + if (!feedback.restoreEncodedModes(initmh, encoded)) { + // Catastrophic corruption -- remove the retained modes + prefs.remove(MODE_KEY); + } } if (commandLineFeedbackMode != null) { // The feedback mode to use was specified on the command line, use it - if (!feedback.setFeedback(initmh, new ArgTokenizer("-feedback ", commandLineFeedbackMode))) { + if (!feedback.setFeedback(initmh, new ArgTokenizer("-feedback", commandLineFeedbackMode))) { regenerateOnDeath = false; } commandLineFeedbackMode = null; @@ -684,7 +687,7 @@ if (fb != null) { // Restore the feedback mode to use that was retained // on a previous run with /retain feedback - feedback.setFeedback(initmh, new ArgTokenizer("/retain feedback ", fb)); + feedback.retainFeedback(initmh, new ArgTokenizer("/retain feedback", fb)); } } } @@ -695,6 +698,7 @@ run(suin); } catch (Exception ex) { hardmsg("jshell.err.startup.unexpected.exception", ex); + ex.printStackTrace(cmdout); } } @@ -1012,9 +1016,10 @@ return state.snippets(); } - List dropableSnippets() { + List dropableSnippets() { return state.snippets().stream() - .filter(sn -> state.status(sn).isActive) + .filter(sn -> state.status(sn).isActive && sn instanceof PersistentSnippet) + .map(sn -> (PersistentSnippet) sn) .collect(toList()); } @@ -1173,14 +1178,14 @@ // --- Command implementations --- private static final String[] SET_SUBCOMMANDS = new String[]{ - "format", "truncation", "feedback", "newmode", "prompt", "editor", "start"}; + "format", "truncation", "feedback", "mode", "prompt", "editor", "start"}; private static final String[] RETAIN_SUBCOMMANDS = new String[]{ "feedback", "mode", "editor", "start"}; final boolean cmdSet(String arg) { String cmd = "/set"; - ArgTokenizer at = new ArgTokenizer(cmd +" ", arg.trim()); + ArgTokenizer at = new ArgTokenizer(cmd, arg.trim()); String which = subCommand(cmd, at, SET_SUBCOMMANDS); if (which == null) { return false; @@ -1192,22 +1197,14 @@ return feedback.setTruncation(this, at); case "feedback": return feedback.setFeedback(this, at); - case "newmode": - return feedback.setNewMode(this, at); + case "mode": + return feedback.setMode(this, at); case "prompt": return feedback.setPrompt(this, at); - case "editor": { - String prog = at.next(); - if (prog == null) { - errormsg("jshell.err.set.editor.arg"); - return false; - } else { - return setEditor(cmd, prog, at); - } - } - case "start": { - return setStart(cmd, at.next()); - } + case "editor": + return setEditor(at, true); + case "start": + return setStart(cmd, at, true); default: errormsg("jshell.err.arg", cmd, at.val()); return false; @@ -1216,7 +1213,7 @@ final boolean cmdRetain(String arg) { String cmd = "/retain"; - ArgTokenizer at = new ArgTokenizer(cmd +" ", arg.trim()); + ArgTokenizer at = new ArgTokenizer(cmd, arg.trim()); String which = subCommand(cmd, at, RETAIN_SUBCOMMANDS); if (which == null) { return false; @@ -1239,33 +1236,22 @@ return true; } return false; - case "editor": { - String prog = at.next(); - if (prog != null) { - // If the editor is specified, first run /set editor ... - if(!setEditor(cmd, prog, at)) { - return false; - } - } - if (editor != null) { - // If an editor has been set now, or in the past, retain it - prefs.put(EDITOR_KEY, String.join(RECORD_SEPARATOR, editor)); - return true; + case "editor": + if (!setEditor(at, false)) { + return false; } - return false; - } + // retain editor setting + prefs.put(EDITOR_KEY, (editor == null) + ? "" + : String.join(RECORD_SEPARATOR, editor)); + return true; case "start": { - String fn = at.next(); - if (fn != null) { - if (!setStart(cmd, fn)) { - return false; - } + if (!setStart(cmd, at, false)) { + return false; } - if (startup != null) { - prefs.put(STARTUP_KEY, startup); - return true; - } - return false; + // retain startup setting + prefs.put(STARTUP_KEY, startup); + return true; } default: errormsg("jshell.err.arg", cmd, at.val()); @@ -1311,28 +1297,60 @@ } // The sub-command: /set editor > - boolean setEditor(String cmd, String prog, ArgTokenizer at) { + boolean setEditor(ArgTokenizer at, boolean argsRequired) { + at.allowedOptions("-default"); + String prog = at.next(); List ed = new ArrayList<>(); - ed.add(prog); - String n; - while ((n = at.next()) != null) { - ed.add(n); + while (at.val() != null) { + ed.add(at.val()); + at.nextToken(); + } + if (!checkOptionsAndRemainingInput(at)) { + return false; } - editor = ed.toArray(new String[ed.size()]); - fluffmsg("jshell.msg.set.editor.set", prog); + boolean defaultOption = at.hasOption("-default"); + if (prog != null) { + if (defaultOption) { + errormsg("jshell.err.default.option.or.program", at.whole()); + return false; + } + editor = ed.toArray(new String[ed.size()]); + fluffmsg("jshell.msg.set.editor.set", prog); + } else if (defaultOption) { + editor = null; + } else if (argsRequired) { + errormsg("jshell.err.set.editor.arg"); + return false; + } return true; } // The sub-command: /set start - boolean setStart(String cmd, String fn) { - String init = readFile(fn, cmd + " start"); - if (init == null) { + boolean setStart(String cmd, ArgTokenizer at, boolean argsRequired) { + at.allowedOptions("-default", "-none"); + String fn = at.next(); + if (!checkOptionsAndRemainingInput(at)) { + return false; + } + int argCount = at.optionCount() + ((fn != null) ? 1 : 0); + if (argCount > 1 || argsRequired && argCount == 0) { + errormsg("jshell.err.option.or.filename", at.whole()); return false; - } else { - startup = init; - //prefs.put(STARTUP_KEY, init); - return true; } + if (fn != null) { + String init = readFile(fn, cmd + " start"); + if (init == null) { + return false; + } else { + startup = init; + return true; + } + } else if (at.hasOption("-default")) { + startup = DEFAULT_STARTUP; + } else if (at.hasOption("-none")) { + startup = ""; + } + return true; } boolean cmdClasspath(String arg) { @@ -1419,7 +1437,7 @@ } boolean cmdHelp(String arg) { - ArgTokenizer at = new ArgTokenizer(arg); + ArgTokenizer at = new ArgTokenizer("/help", arg); String subject = at.next(); if (subject != null) { Command[] matches = commands.values().stream() @@ -1517,116 +1535,137 @@ } /** - * Convert a user argument to a Stream of snippets referenced by that argument - * (or lack of argument). - * - * @param snippets the base list of possible snippets - * @param arg the user's argument to the command, maybe be the empty string - * @param allowAll if true, allow the use of '-all' and '-start' - * @return a Stream of referenced snippets or null if no matches to specific arg - */ - private Stream argToSnippets(List snippets, String arg, boolean allowAll) { - return argToSnippets(snippets, this::mainActive, arg, allowAll); - } - - /** - * Convert a user argument to a Stream of snippets referenced by that argument - * (or lack of argument). + * Convert user arguments to a Stream of snippets referenced by those + * arguments (or lack of arguments). * * @param snippets the base list of possible snippets * @param defFilter the filter to apply to the arguments if no argument - * @param arg the user's argument to the command, maybe be the empty string - * @param allowAll if true, allow the use of '-all' and '-start' - * @return a Stream of referenced snippets or null if no matches to specific arg + * @param rawargs the user's argument to the command, maybe be the empty + * string + * @return a Stream of referenced snippets or null if no matches are found */ - private Stream argToSnippets(List snippets, - Predicate defFilter, String arg, boolean allowAll) { - if (allowAll && arg.equals("-all")) { + private Stream argsOptionsToSnippets(List snippets, + Predicate defFilter, String rawargs, String cmd) { + ArgTokenizer at = new ArgTokenizer(cmd, rawargs.trim()); + at.allowedOptions("-all", "-start"); + List args = new ArrayList<>(); + String s; + while ((s = at.next()) != null) { + args.add(s); + } + if (!checkOptionsAndRemainingInput(at)) { + return null; + } + if (at.optionCount() > 0 && args.size() > 0) { + errormsg("jshell.err.may.not.specify.options.and.snippets", at.whole()); + return null; + } + if (at.optionCount() > 1) { + errormsg("jshell.err.conflicting.options", at.whole()); + return null; + } + if (at.hasOption("-all")) { // all snippets including start-up, failed, and overwritten return snippets.stream(); - } else if (allowAll && arg.equals("-start")) { + } + if (at.hasOption("-start")) { // start-up snippets return snippets.stream() .filter(this::inStartUp); - } else if (arg.isEmpty()) { + } + if (args.isEmpty()) { // Default is all active user snippets return snippets.stream() .filter(defFilter); - } else { - Stream result = - nonEmptyStream( - () -> snippets.stream(), - // look for active user declarations matching the name - sn -> isActive(sn) && matchingDeclaration(sn, arg), - // else, look for any declarations matching the name - sn -> matchingDeclaration(sn, arg), - // else, look for an id of this name - sn -> sn.id().equals(arg) - ); - return result; } + return argsToSnippets(snippets, args); } /** - * Convert a user argument to a Stream of snippets referenced by that - * argument, printing an informative message if no matches. Allow '-all' and - * '-start'. + * Convert user arguments to a Stream of snippets referenced by those + * arguments. * * @param snippets the base list of possible snippets - * @param defFilter the filter to apply to the arguments if no argument - * @param arg the user's argument to the command, maybe be the empty string - * @param cmd the name of the command (for use in a help message + * @param args the user's argument to the command, maybe be the empty list * @return a Stream of referenced snippets or null if no matches to specific * arg */ - private Stream argToSnippetsWithMessage(List snippets, - Predicate defFilter, String arg, String cmd) { - Stream stream = argToSnippets(snippets, defFilter, arg, true); - if (stream == null) { - errormsg("jshell.err.def.or.id.not.found", arg); - // Check if there are any definitions at all - if (argToSnippets(snippets, "", false).iterator().hasNext()) { - fluffmsg("jshell.msg.try.command.without.args", cmd); + private Stream argsToSnippets(List snippets, + List args) { + Stream result = null; + for (String arg : args) { + // Find the best match + Stream st = layeredSnippetSearch(snippets, arg); + if (st == null) { + Stream est = layeredSnippetSearch(state.snippets(), arg); + if (est == null) { + errormsg("jshell.err.no.such.snippets", arg); + } else { + errormsg("jshell.err.the.snippet.cannot.be.used.with.this.command", + arg, est.findFirst().get().source()); + } + return null; + } + if (result == null) { + result = st; } else { - hardmsg("jshell.msg.no.active"); + result = Stream.concat(result, st); } } - return stream; + return result; } - private boolean cmdDrop(String arg) { - if (arg.isEmpty()) { + private Stream layeredSnippetSearch(List snippets, String arg) { + return nonEmptyStream( + // the stream supplier + () -> snippets.stream(), + // look for active user declarations matching the name + sn -> isActive(sn) && matchingDeclaration(sn, arg), + // else, look for any declarations matching the name + sn -> matchingDeclaration(sn, arg), + // else, look for an id of this name + sn -> sn.id().equals(arg) + ); + } + + private boolean cmdDrop(String rawargs) { + ArgTokenizer at = new ArgTokenizer("/drop", rawargs.trim()); + at.allowedOptions(); + List args = new ArrayList<>(); + String s; + while ((s = at.next()) != null) { + args.add(s); + } + if (!checkOptionsAndRemainingInput(at)) { + return false; + } + if (args.isEmpty()) { errormsg("jshell.err.drop.arg"); return false; } - Stream stream = argToSnippets(dropableSnippets(), arg, false); + Stream stream = argsToSnippets(dropableSnippets(), args); if (stream == null) { - errormsg("jshell.err.def.or.id.not.found", arg); + // Snippet not found. Error already printed fluffmsg("jshell.msg.see.classes.etc"); return false; } - List snippets = stream - .filter(sn -> state.status(sn).isActive && sn instanceof PersistentSnippet) - .collect(toList()); - if (snippets.isEmpty()) { - errormsg("jshell.err.drop.not.active"); - return false; - } - if (snippets.size() > 1) { + List snippets = stream.collect(toList()); + if (snippets.size() > args.size()) { + // One of the args references more thean one snippet errormsg("jshell.err.drop.ambiguous"); fluffmsg("jshell.msg.use.one.of", snippets.stream() - .map(sn -> String.format("\n%4s : %s", sn.id(), sn.source().replace("\n", "\n "))) + .map(sn -> String.format("\n/drop %-5s : %s", sn.id(), sn.source().replace("\n", "\n "))) .collect(Collectors.joining(", ")) ); return false; } - PersistentSnippet psn = (PersistentSnippet) snippets.get(0); - state.drop(psn).forEach(this::handleEvent); + snippets.stream() + .forEach(sn -> state.drop(sn).forEach(this::handleEvent)); return true; } private boolean cmdEdit(String arg) { - Stream stream = argToSnippetsWithMessage(state.snippets(), + Stream stream = argsOptionsToSnippets(state.snippets(), this::mainActive, arg, "/edit"); if (stream == null) { return false; @@ -1728,10 +1767,10 @@ } private boolean cmdList(String arg) { - if (arg.equals("-history")) { + if (arg.length() >= 2 && "-history".startsWith(arg)) { return cmdHistory(); } - Stream stream = argToSnippetsWithMessage(state.snippets(), + Stream stream = argsOptionsToSnippets(state.snippets(), this::mainActive, arg, "/list"); if (stream == null) { return false; @@ -1801,75 +1840,63 @@ return true; } - private boolean cmdReload(String arg) { - Iterable history = replayableHistory; - boolean echo = true; - if (arg.length() > 0) { - if ("-restore".startsWith(arg)) { - if (replayableHistoryPrevious == null) { - errormsg("jshell.err.reload.no.previous"); - return false; - } - history = replayableHistoryPrevious; - } else if ("-quiet".startsWith(arg)) { - echo = false; - } else { - errormsg("jshell.err.arg", "/reload", arg); + private boolean cmdReload(String rawargs) { + ArgTokenizer at = new ArgTokenizer("/reload", rawargs.trim()); + at.allowedOptions("-restore", "-quiet"); + if (!checkOptionsAndRemainingInput(at)) { + return false; + } + Iterable history; + if (at.hasOption("-restore")) { + if (replayableHistoryPrevious == null) { + errormsg("jshell.err.reload.no.previous"); return false; } + history = replayableHistoryPrevious; + fluffmsg("jshell.err.reload.restarting.previous.state"); + } else { + history = replayableHistory; + fluffmsg("jshell.err.reload.restarting.state"); } - fluffmsg(history == replayableHistoryPrevious - ? "jshell.err.reload.restarting.previous.state" - : "jshell.err.reload.restarting.state"); + boolean echo = !at.hasOption("-quiet"); resetState(); run(new ReloadIOContext(history, - echo? cmdout : null)); + echo ? cmdout : null)); return true; } - private boolean cmdSave(String arg_filename) { - Matcher mat = HISTORY_ALL_START_FILENAME.matcher(arg_filename); - if (!mat.find()) { - errormsg("jshell.err.arg", arg_filename); + private boolean cmdSave(String rawargs) { + ArgTokenizer at = new ArgTokenizer("/save", rawargs.trim()); + at.allowedOptions("-all", "-start", "-history"); + String filename = at.next(); + if (filename == null) { + errormsg("jshell.err.file.filename", "/save"); return false; } - boolean useHistory = false; - String saveAll = ""; - boolean saveStart = false; - String cmd = mat.group("cmd"); - if (cmd != null) switch (cmd) { - case "-all": - saveAll = "-all"; - break; - case "-history": - useHistory = true; - break; - case "-start": - saveStart = true; - break; + if (!checkOptionsAndRemainingInput(at)) { + return false; } - String filename = mat.group("filename"); - if (filename == null ||filename.isEmpty()) { - errormsg("jshell.err.file.filename", "/save"); + if (at.optionCount() > 1) { + errormsg("jshell.err.conflicting.options", at.whole()); return false; } try (BufferedWriter writer = Files.newBufferedWriter(toPathResolvingUserHome(filename), Charset.defaultCharset(), CREATE, TRUNCATE_EXISTING, WRITE)) { - if (useHistory) { + if (at.hasOption("-history")) { for (String s : input.currentSessionHistory()) { writer.write(s); writer.write("\n"); } - } else if (saveStart) { - writer.append(DEFAULT_STARTUP); + } else if (at.hasOption("-start")) { + writer.append(startup); } else { - Stream stream = argToSnippets(state.snippets(), saveAll, true); - if (stream != null) { - for (Snippet sn : stream.collect(toList())) { - writer.write(sn.source()); - writer.write("\n"); - } + List sns = at.hasOption("-all") + ? state.snippets() + : state.snippets().stream().filter(this::mainActive).collect(toList()); + for (Snippet sn : sns) { + writer.write(sn.source()); + writer.write("\n"); } } } catch (FileNotFoundException e) { @@ -1883,7 +1910,7 @@ } private boolean cmdVars(String arg) { - Stream stream = argToSnippetsWithMessage(allVarSnippets(), + Stream stream = argsOptionsToSnippets(allVarSnippets(), this::isActive, arg, "/vars"); if (stream == null) { return false; @@ -1899,7 +1926,7 @@ } private boolean cmdMethods(String arg) { - Stream stream = argToSnippetsWithMessage(allMethodSnippets(), + Stream stream = argsOptionsToSnippets(allMethodSnippets(), this::isActive, arg, "/methods"); if (stream == null) { return false; @@ -1911,7 +1938,7 @@ } private boolean cmdTypes(String arg) { - Stream stream = argToSnippetsWithMessage(allTypeSnippets(), + Stream stream = argsOptionsToSnippets(allTypeSnippets(), this::isActive, arg, "/types"); if (stream == null) { return false; @@ -1964,6 +1991,21 @@ return true; } + boolean checkOptionsAndRemainingInput(ArgTokenizer at) { + String junk = at.remainder(); + if (!junk.isEmpty()) { + errormsg("jshell.err.unexpected.at.end", junk, at.whole()); + return false; + } else { + String bad = at.badOptions(); + if (!bad.isEmpty()) { + errormsg("jshell.err.unknown.option", bad, at.whole()); + return false; + } + } + return true; + } + private boolean rerunHistoryEntryById(String id) { Optional snippet = state.snippets().stream() .filter(s -> s.id().equals(id)) diff -r 8bdc63ff6961 -r 71874886920f langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Mon May 23 15:07:10 2016 +0100 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Mon May 23 10:12:05 2016 -0700 @@ -37,7 +37,6 @@ Restore definitions with: /reload -restore jshell.msg.use.one.of = Use one of: {0} -jshell.err.def.or.id.not.found = No applicable definition or id found named: {0} jshell.msg.see.classes.etc = See /types, /methods, /vars, or /list jshell.err.arg = Invalid ''{0}'' argument: {1} jshell.msg.see = See {0} for help. @@ -91,7 +90,6 @@ jshell.err.drop.arg =\ In the /drop argument, please specify an import, variable, method, or class to drop.\n\ Specify by id or name. Use /list to see ids. Use /reset to reset all state. -jshell.err.drop.not.active = The argument did not specify an active import, variable, method, or class to drop. jshell.err.drop.ambiguous = The argument references more than one import, variable, method, or class. jshell.err.failed = Failed. jshell.msg.native.method = Native Method @@ -100,11 +98,12 @@ jshell.msg.help.for.help = Type /help for help. -jshell.err.feedback.expected.new.feedback.mode = Expected new feedback mode -- {0} -jshell.err.feedback.expected.mode.name = Expected a new feedback mode name. ''{0}'' is a known feedback mode -- {1} -jshell.err.feedback.command.quiet = Specify either ''-command'' or ''-quiet'' -- {0} -jshell.err.feedback.expected.field = Expected field name missing -- {0} -jshell.err.feedback.expected.mode = Expected a feedback mode -- {0} +jshell.err.mode.name = Expected a feedback mode name: {0} +jshell.err.missing.mode = Missing the feedback mode -- {0} +jshell.err.field.name = Expected a field name: {0} -- {1} +jshell.err.missing.field = Missing the field name -- {0} +jshell.err.mode.unknown = No feedback mode named: {0} -- {1} + jshell.err.feedback.does.not.match.mode = Does not match any current feedback mode: {0} -- {1} jshell.err.feedback.ambiguous.mode = Matches more then one current feedback mode: {0} -- {1} jshell.err.feedback.expected.format = Expected format missing -- {0} @@ -120,10 +119,22 @@ jshell.err.truncation.expected.length = Expected truncation length -- {0} jshell.err.truncation.length.not.integer = Truncation length must be an integer: {0} -- {1} -jshell.err.not.valid.with.predefined.mode = Not valid with predefined modes: {0} -- {1} +jshell.err.not.valid.with.predefined.mode = Not valid with a predefined mode: {0} -- {1} jshell.err.retained.feedback.mode.must.be.retained.or.predefined = \ ''/retain feedback '' requires that is predefined or has been retained with ''/retain mode'' -- {0} +jshell.err.unknown.option = Unknown option: {0} -- {1} +jshell.err.default.option.or.program = Specify -default option or program, not both -- {0} +jshell.err.option.or.filename = Specify either one option or a startup file name -- {0} +jshell.err.unexpected.at.end = Unexpected arguments at end of command: {0} -- {1} +jshell.err.conflicting.options = Conflicting options -- {0} +jshell.err.cannot.delete.current.mode = The current feedback mode ''{0}'' cannot be deleted, use ''/set feedback'' first -- {1} +jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/retain feedback'' first -- {1} +jshell.err.may.not.specify.options.and.snippets = Options and snippets must not both be used: {0} +jshell.err.no.such.snippets = No such snippet: {0} +jshell.err.the.snippet.cannot.be.used.with.this.command = This command does not accept the snippet ''{0}'' : {1} +jshell.err.retained.mode.failure = Failure in retained modes (modes cleared) -- {0} {1} + jshell.console.see.more = jshell.console.do.nothing = Do nothing jshell.console.choice = Choice: \ @@ -341,7 +352,7 @@ Display information about the specified help subject. Example: /help intro help.set.summary = set jshell configuration information -help.set.args = editor|start|feedback|newmode|prompt|truncation|format ... +help.set.args = editor|start|feedback|mode|prompt|truncation|format ... help.set =\ Set jshell configuration information, including:\n\ the external editor to use, the start-up definitions to use, a new feedback mode,\n\ @@ -354,8 +365,8 @@ The contents of the specified become the default start-up snippets and commands.\n\n\ /set feedback \n\t\ Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\ -/set newmode [-command|-quiet []]\n\t\ - Create a user-defined feedback mode, optionally copying from an existing mode.\n\n\ +/set mode [] [-command|-quiet|-delete]\n\t\ + Create or update a user-defined feedback mode, optionally copying from an existing mode.\n\n\ /set prompt "" ""\n\t\ Set the displayed prompts for a given feedback mode.\n\n\ /set truncation ...\n\t\ @@ -452,7 +463,7 @@ \n\t\ /set format "" ...\n\ \n\ -Where is the name of a previously defined feedback mode -- see '/help /set newmode'.\n\ +Where is the name of a previously defined feedback mode -- see '/help /set mode'.\n\ Where is the name of context-specific format to define.\n\ Where is a quoted string which will be the value of the field if one of\n\ the selectors matches (or there are no selectors). When the format is used,\n\ @@ -528,7 +539,7 @@ \n\t\ /set truncation ...\n\ \n\ -Where is the name of a previously defined feedback mode -- see '/help /set newmode'.\n\ +Where is the name of a previously defined feedback mode -- see '/help /set mode'.\n\ Where is an unsigned integer representing a maximum length.\n\ Where is a quoted string which will be the value of the field if one of\n\ Where is only needed if you wish to fine-tune value truncation length\n\ @@ -561,13 +572,13 @@ \n\ Where is the name of a previously defined feedback mode.\n\ You may use just enough letters to make it unique.\n\ -User-defined modes can be added, see '/help /set newmode'\n\ +User-defined modes can be added, see '/help /set mode'\n\ Currently defined feedback modes:\n -help.set.newmode = \ +help.set.mode = \ Create a user-defined feedback mode, optionally copying from an existing mode.\n\ \n\t\ -/set newmode [-command|-quiet []]\n\ +/set mode [] [-command|-quiet|-delete]\n\ \n\ Where is the name of a mode you wish to create.\n\ Where is the name of a previously defined feedback mode.\n\ @@ -591,19 +602,24 @@ help.set.editor =\ Specify the command to launch for the /edit command.\n\ \n\t\ -/set editor \n\ +/set editor |-default\n\ \n\ The is an operating system dependent string.\n\ The may include space-separated arguments (such as flags)\n\ -When /edit is used, the temporary file to edit will be appended as the last argument. +When /edit is used, the temporary file to edit will be appended as the last argument.\n\ +If instead the -default option is specified, the built-in default editor will be used. help.set.start =\ Set the start-up configuration -- a sequence of snippets and commands read at start-up.\n\ \n\t\ -/set start \n\ +/set start |-default|-none\n\ \n\ The contents of the specified become the start-up snippets and commands used\n\ when the /reset or /reload commands are used in this session.\n\ +If instead the -default option is specified, the predefined start-up snippets\n\ +will be used.\n\ +If the -none option is used, the start-up will be empty -- no start-up snippets\n\ +or commands will be used.\n\ This command is good for testing the start-up settings. To retain them for future\n\ runs of the jshell tool use the command:\n\t\ /retain start\n @@ -626,33 +642,42 @@ /retain mode \n\ \n\ Where is the name of a mode you wish to retain.\n\ -The must previously have been created with /set newmode and\n\ +The must previously have been created with /set mode and\n\ configured as desired with /set prompt, /set format, and /set truncation.\n help.retain.editor =\ Retain the command to launch for the /edit command. This command will be invoked when\n\ the /edit command is used in this and future sessions of the jshell tool.\n\ \n\t\ -/retain editor []\n\ +/retain editor [|-default]\n\ \n\ -The is an operating system dependent string.\n\ -The may include space-separated arguments (such as flags)\n\ -When /edit is used, the temporary file to edit will be appended as the last argument.\n\ -If is not specified, the command last specified in a /set editor or\n\ -/retain editor command will be retained.\n +If is specified, it is an operating system dependent string which\n\ +may include space-separated arguments (such as flags). When /edit is used, the\n\ +temporary file to edit will be appended as the last argument.\n\ +If instead the -default option is specified, the built-in default editor will be used.\n\ +If neither is specified, the editor set in the last /set editor or /retain editor\n\ +command will be used.\n\ +The editor will be retained and used in this and future runs of the jshell tool. help.retain.start =\ -Retain the start-up configuration -- a sequence of snippets and commands read at start-up.\n\ +Retain the start-up configuration -- a sequence of snippets and commands read\n\ +at start-up.\n\ \n\t\ -/retain start []\n\ +/retain start [|-default|-none]\n\ \n\ -The contents of the specified become the default start-up snippets and commands --\n\ -which are run when the jshell tool is started or reset.\n\ -If is not specified, the start-up last specified in a /set start or\n\ -/retain start command will be retained.\n +If is specified, the contents of the specified become the\n\ +start-up snippets\n\ +and commands.\n\ +If instead the -default option is specified, the predefined start-up snippets\n\ +will be the start-up.\n\ +If the -none option is used, the start-up will be empty -- no start-up snippets\n\ +or commands will be used.\n\ +If none of these is specified, the start-up is the last specified in a\n\ +''/set start'' or ''/retain start'' command.\n\ +The start-up will be retained and used when the jshell tool is started or reset startup.feedback = \ -/set newmode verbose -command \n\ +/set mode verbose -command \n\ \n\ /set prompt verbose '\\njshell> ' ' ...> ' \n\ \n\ @@ -702,12 +727,12 @@ \n\ /set format verbose result '{name} ==> {value}{post}' added,modified,replaced-ok-primary \n\ \n\ -/set format verbose display '{result}{pre}created scratch variable {name} : {type}{post}' expression-primary \n\ +/set format verbose display '{result}{pre}created scratch variable {name} : {type}{post}' expression-added,modified,replaced-primary \n\ /set format verbose display '{result}{pre}value of {name} : {type}{post}' varvalue-primary \n\ /set format verbose display '{result}{pre}assigned to {name} : {type}{post}' assignment-primary \n\ /set format verbose display '{result}{pre}{action} variable {name} : {type}{resolve}{post}' varinit,vardecl \n\ /set format verbose display '{pre}{action} variable {name}{resolve}{post}' vardecl,varinit-notdefined \n\ -/set format verbose display '{pre}{action} variable {name}{post}' dropped-vardecl,varinit \n\ +/set format verbose display '{pre}{action} variable {name}{post}' dropped-vardecl,varinit,expression \n\ /set format verbose display '{pre}{action} variable {name}, reset to null{post}' replaced-vardecl,varinit-ok-update \n\ \n\ /set format verbose display '{pre}{action} {typeKind} {name}{resolve}{post}' class,interface,enum,annotation \n\ @@ -719,11 +744,11 @@ /set truncation verbose 80\n\ /set truncation verbose 500 varvalue\n\ \n\ -/set newmode normal -command verbose \n\ +/set mode normal -command verbose \n\ /set format normal display '' added,modified,replaced,overwrote,dropped-update \n\ /set format normal display '{pre}{action} variable {name}, reset to null{post}' replaced-vardecl,varinit-ok-update \n\ /set format normal display '{result}' added,modified,replaced-expression,varvalue,assignment,varinit,vardecl-ok-primary \n\ -/set newmode concise -quiet normal \n\ +/set mode concise -quiet normal \n\ \n\ /set prompt concise 'jshell> ' ' ...> ' \n\ \n\ @@ -731,7 +756,7 @@ \n\ /set feedback normal \n\ \n\ -/set newmode silent -quiet \n\ +/set mode silent -quiet \n\ /set prompt silent '-> ' '>> ' \n\ /set format silent pre '| ' \n\ /set format silent post '%n' \n\ diff -r 8bdc63ff6961 -r 71874886920f langtools/test/jdk/jshell/ToolCommandOptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java Mon May 23 10:12:05 2016 -0700 @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + + /* + * @test + * @bug 8157395 8157393 8157517 + * @summary Tests of jshell comand options, and undoing operations + * @modules jdk.jshell/jdk.internal.jshell.tool + * @build ToolCommandOptionTest ReplToolTesting + * @run testng ToolCommandOptionTest + */ +import org.testng.annotations.Test; +import static org.testng.Assert.assertFalse; + +@Test +public class ToolCommandOptionTest extends ReplToolTesting { + + public void listTest() { + test( + (a) -> assertCommand(a, "int x;", + "x ==> 0"), + (a) -> assertCommand(a, "/li", + "1 : int x;"), + (a) -> assertCommandOutputStartsWith(a, "/lis -st", + "\n s1 : import"), + (a) -> assertCommandOutputStartsWith(a, "/list -all", + "\n s1 : import"), + (a) -> assertCommandOutputContains(a, "/list -all", + "1 : int x;"), + (a) -> assertCommandOutputContains(a, "/list -history", + "int x;"), + (a) -> assertCommandOutputContains(a, "/li -h", + "/lis -st"), + (a) -> assertCommand(a, "/list -furball", + "| Unknown option: -furball -- /list -furball"), + (a) -> assertCommand(a, "/list x", + "1 : int x;"), + (a) -> assertCommand(a, "/li x -start", + "| Options and snippets must not both be used: /list x -start"), + (a) -> assertCommand(a, "/l -st -al", + "| Conflicting options -- /list -st -al") + ); + } + + public void typesTest() { + test( + (a) -> assertCommand(a, "int x", + "x ==> 0"), + (a) -> assertCommand(a, "/types x", + "| This command does not accept the snippet 'x' : int x;"), + (a) -> assertCommand(a, "class C {}", + "| created class C"), + (a) -> assertCommand(a, "/ty", + "| class C"), + (a) -> assertCommand(a, "/ty -st", + ""), + (a) -> assertCommand(a, "/types -all", + "| class C"), + (a) -> assertCommand(a, "/types -furball", + "| Unknown option: -furball -- /types -furball"), + (a) -> assertCommand(a, "/types C", + "| class C"), + (a) -> assertCommand(a, "/types C -start", + "| Options and snippets must not both be used: /types C -start"), + (a) -> assertCommand(a, "/ty -st -al", + "| Conflicting options -- /types -st -al") + ); + } + + public void dropTest() { + test(false, new String[]{"-nostartup"}, + (a) -> assertCommand(a, "int x = 5;", + "x ==> 5"), + (a) -> assertCommand(a, "x", + "x ==> 5"), + (a) -> assertCommand(a, "long y;", + "y ==> 0"), + (a) -> assertCommand(a, "/drop -furball", + "| Unknown option: -furball -- /drop -furball"), + (a) -> assertCommand(a, "/drop -all", + "| Unknown option: -all -- /drop -all"), + (a) -> assertCommandOutputStartsWith(a, "/drop z", + "| No such snippet: z"), + (a) -> assertCommandOutputStartsWith(a, "/drop 2", + "| This command does not accept the snippet '2' : x"), + (a) -> assertCommand(a, "/dr x y", + "| dropped variable x\n" + + "| dropped variable y"), + (a) -> assertCommand(a, "/list", + "2 : x") + ); + } + + public void setEditorTest() { + test( + (a) -> assertCommand(a, "/set editor -furball", + "| Unknown option: -furball -- /set editor -furball"), + (a) -> assertCommand(a, "/set editor -furball prog", + "| Unknown option: -furball -- /set editor -furball prog"), + (a) -> assertCommand(a, "/set editor -furball -mattress", + "| Unknown option: -furball -mattress -- /set editor -furball -mattress"), + (a) -> assertCommand(a, "/set editor -default prog", + "| Specify -default option or program, not both -- /set editor -default prog"), + (a) -> assertCommand(a, "/set editor prog", + "| Editor set to: prog"), + (a) -> assertCommand(a, "/set editor prog -default", + "| Editor set to: prog"), + (a) -> assertCommand(a, "/se ed prog -furball", + "| Editor set to: prog"), + (a) -> assertCommand(a, "/set editor prog arg1 -furball arg3 -default arg4", + "| Editor set to: prog"), + (a) -> assertCommand(a, "/set editor -default", + ""), + (a) -> assertCommand(a, "/se edi -def", + ""), + (a) -> assertCommand(a, "/set editor", + "| The '/set editor' command requires a path argument") + ); + } + + public void retainEditorTest() { + test( + (a) -> assertCommand(a, "/retain editor -furball", + "| Unknown option: -furball -- /retain editor -furball"), + (a) -> assertCommand(a, "/retain editor -furball prog", + "| Unknown option: -furball -- /retain editor -furball prog"), + (a) -> assertCommand(a, "/retain editor -furball -mattress", + "| Unknown option: -furball -mattress -- /retain editor -furball -mattress"), + (a) -> assertCommand(a, "/retain editor -default prog", + "| Specify -default option or program, not both -- /retain editor -default prog"), + (a) -> assertCommand(a, "/retain editor prog", + "| Editor set to: prog"), + (a) -> assertCommand(a, "/retain editor prog -default", + "| Editor set to: prog"), + (a) -> assertCommand(a, "/ret ed prog -furball", + "| Editor set to: prog"), + (a) -> assertCommand(a, "/retain editor prog arg1 -furball arg3 -default arg4", + "| Editor set to: prog"), + (a) -> assertCommand(a, "/retain editor -default", + ""), + (a) -> assertCommand(a, "/reta edi -def", + ""), + (a) -> assertCommand(a, "/retain editor", + "") + ); + } + + public void setStartTest() { + test( + (a) -> assertCommand(a, "/set start -furball", + "| Unknown option: -furball -- /set start -furball"), + (a) -> assertCommand(a, "/set start -furball pyle", + "| Unknown option: -furball -- /set start -furball pyle"), + (a) -> assertCommand(a, "/se st pyle -furball", + "| Unknown option: -furball -- /set st pyle -furball"), + (a) -> assertCommand(a, "/set start -furball -mattress", + "| Unknown option: -furball -mattress -- /set start -furball -mattress"), + (a) -> assertCommand(a, "/set start foo -default", + "| Specify either one option or a startup file name -- /set start foo -default"), + (a) -> assertCommand(a, "/set start frfg", + "| File 'frfg' for '/set start' is not found."), + (a) -> assertCommand(a, "/set start -default", + ""), + (a) -> assertCommand(a, "/se sta -no", + ""), + (a) -> assertCommand(a, "/set start", + "| Specify either one option or a startup file name -- /set start") + ); + } + + public void retainStartTest() { + test( + (a) -> assertCommand(a, "/retain start -furball", + "| Unknown option: -furball -- /retain start -furball"), + (a) -> assertCommand(a, "/retain start -furball pyle", + "| Unknown option: -furball -- /retain start -furball pyle"), + (a) -> assertCommand(a, "/ret st pyle -furball", + "| Unknown option: -furball -- /retain st pyle -furball"), + (a) -> assertCommand(a, "/retain start -furball -mattress", + "| Unknown option: -furball -mattress -- /retain start -furball -mattress"), + (a) -> assertCommand(a, "/retain start foo -default", + "| Specify either one option or a startup file name -- /retain start foo -default"), + (a) -> assertCommand(a, "/retain start frfg", + "| File 'frfg' for '/retain start' is not found."), + (a) -> assertCommand(a, "/retain start -default", + ""), + (a) -> assertCommand(a, "/ret sta -no", + ""), + (a) -> assertCommand(a, "/retain start", + "") + ); + } + + public void setModeTest() { + test( + (a) -> assertCommandOutputStartsWith(a, "/set mode", + "| Missing the feedback mode"), + (a) -> assertCommandOutputStartsWith(a, "/set mode *", + "| Expected a feedback mode name: *"), + (a) -> assertCommandOutputStartsWith(a, "/set mode -quiet", + "| Missing the feedback mode"), + (a) -> assertCommandOutputStartsWith(a, "/set mode -quiet *", + "| Expected a feedback mode name: *"), + (a) -> assertCommandOutputStartsWith(a, "/set mode amode normal thing", + "| Unexpected arguments at end of command: thing"), + (a) -> assertCommand(a, "/set mode mymode", + "| Created new feedback mode: mymode"), + (a) -> assertCommand(a, "/set mode mymode -delete", + ""), + (a) -> assertCommand(a, "/set mode mymode normal", + "| Created new feedback mode: mymode"), + (a) -> assertCommand(a, "/set mode -del mymode", + ""), + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -command -quiet", + "| Conflicting options"), + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete -quiet", + "| Conflicting options"), + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -command -delete", + "| Conflicting options"), + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -d", + "| No feedback mode named: mymode"), + (a) -> assertCommandOutputStartsWith(a, "/set mode normal", + "| Not valid with a predefined mode: normal"), + (a) -> assertCommand(a, "/se mo -c mymode", + "| Created new feedback mode: mymode"), + (a) -> assertCommand(a, "/set feedback mymode", + "| Feedback mode: mymode"), + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete", + "| The current feedback mode 'mymode' cannot be deleted"), + (a) -> assertCommand(a, "/set feedback no", + "| Feedback mode: normal"), + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete", + ""), + (a) -> assertCommandCheckOutput(a, "/set feedback", + (s) -> assertFalse(s.contains("mymode"), "Didn't delete: " + s)) + ); + } + + public void setModeSmashTest() { + test( + (a) -> assertCommand(a, "/set mode mymode -command", + "| Created new feedback mode: mymode"), + (a) -> assertCommand(a, "/set feedback mymode", + "| Feedback mode: mymode"), + (a) -> assertCommand(a, "/set format mymode display 'blurb'", + ""), + (a) -> assertCommand(a, "45", + "blurb"), + (a) -> assertCommand(a, "/set mode mymode normal", + "| Created new feedback mode: mymode"), + (a) -> assertCommandOutputContains(a, "45", + " ==> 45") + ); + } + + public void retainModeTest() { + test( + (a) -> assertCommandOutputStartsWith(a, "/retain mode", + "| Missing the feedback mode"), + (a) -> assertCommandOutputStartsWith(a, "/retain mode *", + "| Expected a feedback mode name: *"), + (a) -> assertCommandOutputStartsWith(a, "/retain mode amode normal", + "| Unexpected arguments at end of command: normal"), + (a) -> assertCommandOutputStartsWith(a, "/retain mode mymode", + "| Does not match any current feedback mode: mymode"), + (a) -> assertCommandOutputStartsWith(a, "/retain mode mymode -delete", + "| No feedback mode named: mymode"), + (a) -> assertCommandOutputStartsWith(a, "/retain mode -d mymode", + "| No feedback mode named: mymode"), + (a) -> assertCommandOutputStartsWith(a, "/retain mode normal", + "| Not valid with a predefined mode: normal"), + (a) -> assertCommand(a, "/set mode mymode verbose", + "| Created new feedback mode: mymode"), + (a) -> assertCommand(a, "/retain mode mymode", + ""), + (a) -> assertCommand(a, "/set mode mymode -delete", + ""), + (a) -> assertCommand(a, "/retain mode mymode -delete", + ""), + (a) -> assertCommand(a, "/set mode kmode normal", + "| Created new feedback mode: kmode"), + (a) -> assertCommand(a, "/retain mode kmode", + ""), + (a) -> assertCommand(a, "/set mode kmode -delete", + ""), + (a) -> assertCommand(a, "/set mode tmode normal", + "| Created new feedback mode: tmode"), + (a) -> assertCommandOutputStartsWith(a, "/retain feedback tmode", + "| '/retain feedback ' requires that is predefined or has been retained with '/retain mode'"), + (a) -> assertCommand(a, "/set format tmode display 'YES'", + ""), + (a) -> assertCommand(a, "/set feedback tmode", + "| Feedback mode: tmode"), + (a) -> assertCommand(a, "45", + "YES"), + (a) -> assertCommand(a, "/retain mode tmode", + ""), + (a) -> assertCommand(a, "/retain feedback tmode", + "| Feedback mode: tmode"), + (a) -> assertCommand(a, "/set format tmode display 'blurb'", + ""), + (a) -> assertCommand(a, "45", + "blurb") + ); + test( + (a) -> assertCommand(a, "45", + "YES"), + (a) -> assertCommand(a, "/set feedback kmode", + "| Feedback mode: kmode"), + (a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete", + "| The current feedback mode 'kmode' cannot be deleted"), + (a) -> assertCommandOutputStartsWith(a, "/retain mode tmode -delete", + "| The retained feedback mode 'tmode' cannot be deleted"), + (a) -> assertCommand(a, "/retain feedback normal", + "| Feedback mode: normal"), + (a) -> assertCommand(a, "/retain mode tmode -delete", + ""), + (a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete", + "") + ); + test( + (a) -> assertCommandOutputStartsWith(a, "/set feedback tmode", + "| Does not match any current feedback mode: tmode"), + (a) -> assertCommandOutputStartsWith(a, "/set feedback kmode", + "| Does not match any current feedback mode: kmode"), + (a) -> assertCommandOutputStartsWith(a, "/set feedback mymode", + "| Does not match any current feedback mode: mymode"), + (a) -> assertCommandCheckOutput(a, "/set feedback", + (s) -> assertFalse(s.contains("mymode"), "Didn't delete mymode: " + s)), + (a) -> assertCommandCheckOutput(a, "/set feedback", + (s) -> assertFalse(s.contains("kmode"), "Didn't delete kmode: " + s)), + (a) -> assertCommandCheckOutput(a, "/set feedback", + (s) -> assertFalse(s.contains("tmode"), "Didn't delete tmode: " + s)) + ); + } + +} diff -r 8bdc63ff6961 -r 71874886920f langtools/test/jdk/jshell/ToolFormatTest.java --- a/langtools/test/jdk/jshell/ToolFormatTest.java Mon May 23 15:07:10 2016 +0100 +++ b/langtools/test/jdk/jshell/ToolFormatTest.java Mon May 23 10:12:05 2016 -0700 @@ -43,7 +43,7 @@ public void testSetFormat() { try { test( - (a) -> assertCommandOutputStartsWith(a, "/set newmode test -command", "| Created new feedback mode: test"), + (a) -> assertCommandOutputStartsWith(a, "/set mode test -command", "| Created new feedback mode: test"), (a) -> assertCommand(a, "/set format test pre '$ '", ""), (a) -> assertCommand(a, "/set format test post ''", ""), (a) -> assertCommand(a, "/set format test act 'ADD' added", ""), @@ -82,7 +82,7 @@ public void testSetFormatSelector() { List tests = new ArrayList<>(); - tests.add((a) -> assertCommandOutputStartsWith(a, "/set newmode ate -quiet", + tests.add((a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet", "| Created new feedback mode: ate")); tests.add((a) -> assertCommand(a, "/set feedback ate", "")); StringBuilder sb = new StringBuilder(); @@ -162,7 +162,7 @@ (a) -> assertCommand(a, "String s = java.util.stream.IntStream.range(65, 74)"+ ".mapToObj(i -> \"\"+(char)i).reduce((a,b) -> a + b + a).get()", "s ==> \"ABACABADABACABAEABACABADABACABAFABACABADABACABAEABACABADABACABAGABACABADABA ..."), - (a) -> assertCommandOutputStartsWith(a, "/set newmode test -quiet", ""), + (a) -> assertCommandOutputStartsWith(a, "/set mode test -quiet", ""), (a) -> assertCommandOutputStartsWith(a, "/set feedback test", ""), (a) -> assertCommand(a, "/set format test display '{type}:{value}' primary", ""), (a) -> assertCommand(a, "/set truncation test 20", ""), @@ -187,13 +187,13 @@ public void testSetNewModeQuiet() { try { test( - (a) -> assertCommandOutputStartsWith(a, "/set newmode nmq -quiet normal", "| Created new feedback mode: nmq"), + (a) -> assertCommandOutputStartsWith(a, "/set mode nmq -quiet normal", "| Created new feedback mode: nmq"), (a) -> assertCommand(a, "/set feedback nmq", ""), - (a) -> assertCommand(a, "/se ne nmq2 -q nor", ""), + (a) -> assertCommand(a, "/se mo nmq2 -q nor", ""), (a) -> assertCommand(a, "/se fee nmq2", ""), - (a) -> assertCommand(a, "/set newmode nmc -command normal", ""), + (a) -> assertCommand(a, "/set mode nmc -command normal", ""), (a) -> assertCommandOutputStartsWith(a, "/set feedback nmc", "| Feedback mode: nmc"), - (a) -> assertCommandOutputStartsWith(a, "/set newmode nm", "| Created new feedback mode: nm"), + (a) -> assertCommandOutputStartsWith(a, "/set mode nm", "| Created new feedback mode: nm"), (a) -> assertCommandOutputStartsWith(a, "/set feedback nm", "| Feedback mode: nm"), (a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal") ); @@ -206,15 +206,15 @@ public void testSetError() { try { test( - (a) -> assertCommandOutputStartsWith(a, "/set newmode tee -command foo", + (a) -> assertCommandOutputStartsWith(a, "/set mode tee -command foo", "| Does not match any current feedback mode: foo"), - (a) -> assertCommandOutputStartsWith(a, "/set newmode tee flurb", - "| Specify either '-command' or '-quiet'"), - (a) -> assertCommandOutputStartsWith(a, "/set newmode te2", - "| Created new feedback mode: te2"), - (a) -> assertCommandOutputStartsWith(a, "/set newmode te2 -command", - "| Expected a new feedback mode name. 'te2' is a known feedback mode"), - (a) -> assertCommandOutputStartsWith(a, "/set newmode te -command normal", + (a) -> assertCommandOutputStartsWith(a, "/set mode tee flurb", + "| Does not match any current feedback mode: flurb"), + (a) -> assertCommandOutputStartsWith(a, "/set mode tee", + "| Created new feedback mode: tee"), + (a) -> assertCommandOutputStartsWith(a, "/set mode verbose", + "| Not valid with a predefined mode: verbose"), + (a) -> assertCommandOutputStartsWith(a, "/set mode te -command normal", "| Created new feedback mode: te"), (a) -> assertCommand(a, "/set format te errorpre 'ERROR: '", ""), (a) -> assertCommandOutputStartsWith(a, "/set feedback te", @@ -226,17 +226,17 @@ (a) -> assertCommandOutputStartsWith(a, "/set f", "ERROR: Ambiguous sub-command argument to '/set': f"), (a) -> assertCommandOutputStartsWith(a, "/set feedback", - "ERROR: Expected a feedback mode"), + "ERROR: Missing the feedback mode"), (a) -> assertCommandOutputStartsWith(a, "/set feedback xyz", "ERROR: Does not match any current feedback mode"), (a) -> assertCommandOutputStartsWith(a, "/set format", - "ERROR: Expected a feedback mode"), + "ERROR: Missing the feedback mode"), (a) -> assertCommandOutputStartsWith(a, "/set format xyz", "ERROR: Does not match any current feedback mode"), (a) -> assertCommandOutputStartsWith(a, "/set format t", "ERROR: Matches more then one current feedback mode: t"), (a) -> assertCommandOutputStartsWith(a, "/set format te", - "ERROR: Expected field name missing"), + "ERROR: Missing the field name"), (a) -> assertCommandOutputStartsWith(a, "/set format te fld", "ERROR: Expected format missing"), (a) -> assertCommandOutputStartsWith(a, "/set format te fld aaa", @@ -255,16 +255,12 @@ "ERROR: Expected truncation length"), (a) -> assertCommandOutputStartsWith(a, "/set truncation te 111 import,added", "ERROR: Different selector kinds in same sections of"), - (a) -> assertCommandOutputStartsWith(a, "/set newmode", - "ERROR: Expected new feedback mode"), - (a) -> assertCommandOutputStartsWith(a, "/set newmode te", - "ERROR: Expected a new feedback mode name"), - (a) -> assertCommandOutputStartsWith(a, "/set newmode x xyz", - "ERROR: Specify either '-command' or '-quiet'"), - (a) -> assertCommandOutputStartsWith(a, "/set newmode x -quiet y", + (a) -> assertCommandOutputStartsWith(a, "/set mode", + "ERROR: Missing the feedback mode"), + (a) -> assertCommandOutputStartsWith(a, "/set mode x -quiet y", "ERROR: Does not match any current feedback mode"), (a) -> assertCommandOutputStartsWith(a, "/set prompt", - "ERROR: Expected a feedback mode"), + "ERROR: Missing the feedback mode"), (a) -> assertCommandOutputStartsWith(a, "/set prompt te", "ERROR: Expected format missing"), (a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa xyz", @@ -272,7 +268,7 @@ (a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa' xyz", "ERROR: Format 'xyz' must be quoted"), (a) -> assertCommandOutputStartsWith(a, "/set prompt", - "ERROR: Expected a feedback mode"), + "ERROR: Missing the feedback mode"), (a) -> assertCommandOutputStartsWith(a, "/set prompt te", "ERROR: Expected format missing"), (a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa", diff -r 8bdc63ff6961 -r 71874886920f langtools/test/jdk/jshell/ToolLocaleMessageTest.java --- a/langtools/test/jdk/jshell/ToolLocaleMessageTest.java Mon May 23 15:07:10 2016 +0100 +++ b/langtools/test/jdk/jshell/ToolLocaleMessageTest.java Mon May 23 10:12:05 2016 -0700 @@ -76,7 +76,7 @@ public void testSample() { try { testLocale( - (a) -> assertCommandOK(a, "/set newmode test -command normal", "test"), + (a) -> assertCommandOK(a, "/set mode test -command normal", "test"), (a) -> assertCommandOK(a, "/set format test errorpre 'ERROR: '"), (a) -> assertCommandOK(a, "/set feedback test", "test"), @@ -101,7 +101,7 @@ public void testCommand() { try { testLocale( - (a) -> assertCommandOK(a, "/set newmode test -command normal", "test"), + (a) -> assertCommandOK(a, "/set mode test -command normal", "test"), (a) -> assertCommandOK(a, "/set format test errorpre 'ERROR: '"), (a) -> assertCommandOK(a, "/set feedback test", "test"), @@ -118,10 +118,10 @@ (a) -> assertCommandOK(a, "int dup"), (a) -> assertCommandFail(a, "/drop dup"), (a) -> assertCommandFail(a, "/edit zebra", "zebra"), - (a) -> assertCommandFail(a, "/list zebra", "zebra", "/list"), + (a) -> assertCommandFail(a, "/list zebra", "zebra", "No such snippet: zebra"), (a) -> assertCommandFail(a, "/open", "/open"), (a) -> assertCommandFail(a, "/open zebra", "zebra", "/open"), - (a) -> assertCommandFail(a, "/reload zebra", "zebra", "/reload"), + (a) -> assertCommandFail(a, "/reload zebra", "zebra", "Unexpected arguments at end of command"), (a) -> assertCommandFail(a, "/save", "/save"), (a) -> assertCommandFail(a, "/-99"), @@ -142,12 +142,12 @@ (a) -> assertCommandOK(a, "/help /open", "/open"), (a) -> assertCommandOK(a, "/help /reload", "-restore"), (a) -> assertCommandOK(a, "/help /help", "intro"), - (a) -> assertCommandOK(a, "/help /set", "newmode"), + (a) -> assertCommandOK(a, "/help /set", "mode"), (a) -> assertCommandOK(a, "/help /?", "intro"), (a) -> assertCommandOK(a, "/help intro", "/help"), (a) -> assertCommandOK(a, "/help /set format", "import", "case", "{value}", "added"), - (a) -> assertCommandOK(a, "/help /set feedback", "newmode"), - (a) -> assertCommandOK(a, "/help /set newmode", "feedback"), + (a) -> assertCommandOK(a, "/help /set feedback", "mode"), + (a) -> assertCommandOK(a, "/help /set mode", "feedback"), (a) -> assertCommandOK(a, "/help /set prompt", "/set prompt"), (a) -> assertCommandOK(a, "/help /set editor", "/edit") ); @@ -156,11 +156,11 @@ public void testFeedbackError() { try { testLocale( - (a) -> assertCommandOK(a, "/set newmode tee -command foo", "foo"), - (a) -> assertCommandOK(a, "/set newmode tee flurb", "-command", "-quiet"), - (a) -> assertCommandOK(a, "/set newmode te2", "te2"), - (a) -> assertCommandOK(a, "/set newmode te2 -command", "te2"), - (a) -> assertCommandOK(a, "/set newmode te -command normal", "te"), + (a) -> assertCommandOK(a, "/set mode te2", "te2"), + (a) -> assertCommandOK(a, "/set mode te3 -command", "te3"), + (a) -> assertCommandOK(a, "/set mode te2 -command"), + (a) -> assertCommandOK(a, "/set mode te -command normal", "te"), + (a) -> assertCommandOK(a, "/set mode te"), (a) -> assertCommandOK(a, "/set format te errorpre 'ERROR: '"), (a) -> assertCommandOK(a, "/set feedback te"), @@ -179,16 +179,14 @@ (a) -> assertCommandFail(a, "/set format te fld 'aaa' import-frog"), (a) -> assertCommandFail(a, "/set format te fld 'aaa' import-import"), (a) -> assertCommandFail(a, "/set format te fld 'aaa' import,added"), - (a) -> assertCommandFail(a, "/set newmode"), - (a) -> assertCommandFail(a, "/set newmode te"), - (a) -> assertCommandFail(a, "/set newmode x xyz"), - (a) -> assertCommandFail(a, "/set newmode x -quiet y"), + (a) -> assertCommandFail(a, "/set mode"), + (a) -> assertCommandFail(a, "/set mode x xyz"), + (a) -> assertCommandFail(a, "/set mode x -quiet y"), + (a) -> assertCommandFail(a, "/set mode tee -command foo", "foo"), (a) -> assertCommandFail(a, "/set prompt"), (a) -> assertCommandFail(a, "/set prompt te"), (a) -> assertCommandFail(a, "/set prompt te aaa xyz", "aaa"), (a) -> assertCommandFail(a, "/set prompt te 'aaa' xyz", "xyz"), - (a) -> assertCommandFail(a, "/set prompt"), - (a) -> assertCommandFail(a, "/set prompt te"), (a) -> assertCommandFail(a, "/set prompt te aaa"), (a) -> assertCommandFail(a, "/set prompt te 'aaa'"), diff -r 8bdc63ff6961 -r 71874886920f langtools/test/jdk/jshell/ToolRetainTest.java --- a/langtools/test/jdk/jshell/ToolRetainTest.java Mon May 23 15:07:10 2016 +0100 +++ b/langtools/test/jdk/jshell/ToolRetainTest.java Mon May 23 10:12:05 2016 -0700 @@ -37,7 +37,7 @@ public void testRetainMode() { test( - (a) -> assertCommand(a, "/set newmode trm -quiet", "| Created new feedback mode: trm"), + (a) -> assertCommand(a, "/set mode trm -quiet", "| Created new feedback mode: trm"), (a) -> assertCommand(a, "/set feedback trm", ""), (a) -> assertCommand(a, "/set format trm display '{name}:{value}'", ""), (a) -> assertCommand(a, "int x = 45", "x:45"), @@ -52,7 +52,7 @@ public void testRetain2Mode() { test( - (a) -> assertCommand(a, "/set newmode trm1 -quiet", "| Created new feedback mode: trm1"), + (a) -> assertCommand(a, "/set mode trm1 -quiet", "| Created new feedback mode: trm1"), (a) -> assertCommand(a, "/retain mode trm1", ""), (a) -> assertCommand(a, "/retain feedback trm1", ""), (a) -> assertCommand(a, "/set format trm1 display '{name}:{value}'", ""), @@ -61,7 +61,7 @@ (a) -> assertCommand(a, "/exit", "") ); test( - (a) -> assertCommand(a, "/set newmode trm2 -quiet", ""), + (a) -> assertCommand(a, "/set mode trm2 -quiet", ""), (a) -> assertCommand(a, "/set format trm2 display '{name}={value}'", ""), (a) -> assertCommand(a, "int x = 45", "x:45"), (a) -> assertCommand(a, "/retain mode trm2", ""), @@ -121,9 +121,9 @@ public void testRetainModeNeg() { test( (a) -> assertCommandOutputStartsWith(a, "/retain mode verbose", - "| Not valid with predefined mode"), + "| Not valid with a predefined mode"), (a) -> assertCommandOutputStartsWith(a, "/retain mode ????", - "| Expected a feedback mode") + "| Expected a feedback mode name: ????") ); } @@ -131,18 +131,18 @@ test( (a) -> assertCommandOutputStartsWith(a, "/retain feedback babble1", "| Does not match any current feedback mode"), - (a) -> assertCommand(a, "/set newmode trfn", + (a) -> assertCommand(a, "/set mode trfn", "| Created new feedback mode: trfn"), (a) -> assertCommandOutputContains(a, "/retain feedback trfn", "is predefined or has been retained"), (a) -> assertCommandOutputStartsWith(a, "/retain feedback !!!!", - "| Expected a feedback mode") + "| Expected a feedback mode name: !!!!") ); } public void testNoRetainMode() { test( - (a) -> assertCommand(a, "/set newmode trm -quiet", "| Created new feedback mode: trm"), + (a) -> assertCommand(a, "/set mode trm -quiet", "| Created new feedback mode: trm"), (a) -> assertCommand(a, "/set feedback trm", ""), (a) -> assertCommand(a, "/set format trm display '{name}:{value}'", ""), (a) -> assertCommand(a, "int x = 45", "x:45"), diff -r 8bdc63ff6961 -r 71874886920f langtools/test/jdk/jshell/ToolSimpleTest.java --- a/langtools/test/jdk/jshell/ToolSimpleTest.java Mon May 23 15:07:10 2016 +0100 +++ b/langtools/test/jdk/jshell/ToolSimpleTest.java Mon May 23 10:12:05 2016 -0700 @@ -179,15 +179,14 @@ } public void testNoArgument() { - String[] commands = {"/save", "/open", "/set start"}; - test(Stream.of(commands) - .map(cmd -> { - String c = cmd; - final String finalC = c; - return (ReplTest) after -> assertCommand(after, cmd, - "| '" + finalC + "' requires a filename argument."); - }) - .toArray(ReplTest[]::new)); + test( + (a) -> assertCommand(a, "/save", + "| '/save' requires a filename argument."), + (a) -> assertCommand(a, "/open", + "| '/open' requires a filename argument."), + (a) -> assertCommand(a, "/set start", + "| Specify either one option or a startup file name -- /set start") + ); } public void testDebug() { @@ -230,13 +229,15 @@ public void testDropNegative() { test(false, new String[]{"-nostartup"}, - a -> assertCommandOutputStartsWith(a, "/drop 0", "| No applicable definition or id found named: 0"), - a -> assertCommandOutputStartsWith(a, "/drop a", "| No applicable definition or id found named: a"), + a -> assertCommandOutputStartsWith(a, "/drop 0", "| No such snippet: 0"), + a -> assertCommandOutputStartsWith(a, "/drop a", "| No such snippet: a"), a -> assertCommandCheckOutput(a, "/drop", assertStartsWith("| In the /drop argument, please specify an import, variable, method, or class to drop.")), a -> assertVariable(a, "int", "a"), a -> assertCommand(a, "a", "a ==> 0"), - a -> assertCommand(a, "/drop 2", "| The argument did not specify an active import, variable, method, or class to drop.") + a -> assertCommand(a, "/drop 2", + "| This command does not accept the snippet '2' : a\n" + + "| See /types, /methods, /vars, or /list") ); } @@ -317,7 +318,7 @@ a -> assertCommandCheckOutput(a, "/list -all", s -> checkLineToList(s, START_UP)), a -> assertCommandOutputStartsWith(a, "/list " + arg, - "| No applicable definition or id found named: " + arg), + "| No such snippet: " + arg), a -> assertVariable(a, "int", "aardvark"), a -> assertCommandOutputContains(a, "/list aardvark", "aardvark"), a -> assertCommandCheckOutput(a, "/list -start", @@ -327,7 +328,7 @@ a -> assertCommandCheckOutput(a, "/list printf", s -> assertTrue(s.contains("void printf"))), a -> assertCommandOutputStartsWith(a, "/list " + arg, - "| No applicable definition or id found named: " + arg) + "| No such snippet: " + arg) ); } @@ -337,21 +338,22 @@ test( a -> assertCommandCheckOutput(a, "/vars -all", s -> checkLineToList(s, startVarList)), - a -> assertCommandOutputStartsWith(a, "/vars " + arg, - "| No applicable definition or id found named: " + arg), + a -> assertCommand(a, "/vars " + arg, + "| No such snippet: " + arg), a -> assertVariable(a, "int", "aardvark"), a -> assertMethod(a, "int f() { return 0; }", "()int", "f"), a -> assertVariable(a, "int", "a"), a -> assertVariable(a, "double", "a", "1", "1.0"), - a -> assertCommandOutputStartsWith(a, "/vars aardvark", "| int aardvark = 0"), + a -> assertCommandOutputStartsWith(a, "/vars aardvark", + "| int aardvark = 0"), a -> assertCommandCheckOutput(a, "/vars -start", s -> checkLineToList(s, startVarList)), a -> assertCommandOutputStartsWith(a, "/vars -all", "| int aardvark = 0\n| int a = "), a -> assertCommandOutputStartsWith(a, "/vars printf", - "| No applicable definition or id found named: printf"), - a -> assertCommandOutputStartsWith(a, "/vars " + arg, - "| No applicable definition or id found named: " + arg) + "| This command does not accept the snippet 'printf'"), + a -> assertCommand(a, "/var " + arg, + "| No such snippet: " + arg) ); } @@ -368,15 +370,15 @@ a -> assertCommandCheckOutput(a, "/methods", s -> checkLineToList(s, startMethodList)), a -> assertCommandOutputStartsWith(a, "/methods " + arg, - "| No applicable definition or id found named: " + arg), + "| No such snippet: " + arg), a -> assertMethod(a, "int f() { return 0; }", "()int", "f"), a -> assertVariable(a, "int", "aardvark"), a -> assertMethod(a, "void f(int a) { g(); }", "(int)void", "f"), a -> assertMethod(a, "void g() {}", "()void", "g"), a -> assertCommandOutputStartsWith(a, "/methods " + arg, - "| No applicable definition or id found named: " + arg), + "| No such snippet: " + arg), a -> assertCommandOutputStartsWith(a, "/methods aardvark", - "| No applicable definition or id found named: aardvark"), + "| This command does not accept the snippet 'aardvark' : int aardvark"), a -> assertCommandCheckOutput(a, "/methods -start", s -> checkLineToList(s, startMethodList)), a -> assertCommandCheckOutput(a, "/methods printf", @@ -398,7 +400,7 @@ a -> assertCommandCheckOutput(a, "/types -start", s -> checkLineToList(s, startTypeList)), a -> assertCommandOutputStartsWith(a, "/types " + arg, - "| No applicable definition or id found named: " + arg), + "| No such snippet: " + arg), a -> assertVariable(a, "int", "aardvark"), (a) -> assertClass(a, "class A { }", "class", "A"), (a) -> assertClass(a, "interface A { }", "interface", "A"), @@ -407,8 +409,8 @@ "| interface A"), (a) -> assertClass(a, "enum E { }", "enum", "E"), (a) -> assertClass(a, "@interface B { }", "@interface", "B"), - a -> assertCommandOutputStartsWith(a, "/types aardvark", - "| No applicable definition or id found named: aardvark"), + a -> assertCommand(a, "/types aardvark", + "| This command does not accept the snippet 'aardvark' : int aardvark;"), a -> assertCommandOutputStartsWith(a, "/types A", "| interface A"), a -> assertCommandOutputStartsWith(a, "/types E", @@ -416,7 +418,7 @@ a -> assertCommandOutputStartsWith(a, "/types B", "| @interface B"), a -> assertCommandOutputStartsWith(a, "/types " + arg, - "| No applicable definition or id found named: " + arg), + "| No such snippet: " + arg), a -> assertCommandCheckOutput(a, "/types -start", s -> checkLineToList(s, startTypeList)) );