8153920: jshell tool: allow a parameter on the /vars /methods /classes commands
Reviewed-by: vromero
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Mon May 16 21:25:44 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Mon May 16 21:46:32 2016 -0700
@@ -917,11 +917,10 @@
p.getFileName().toString().endsWith(".jar"));
}
- private CompletionProvider editCompletion() {
+ private CompletionProvider snippetCompletion(Supplier<List<? extends Snippet>> snippetsSupplier) {
return (prefix, cursor, anchor) -> {
anchor[0] = 0;
- return state.snippets()
- .stream()
+ return snippetsSupplier.get() .stream()
.flatMap(k -> (k instanceof DeclarationSnippet)
? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name())
: Stream.of(String.valueOf(k.id())))
@@ -931,11 +930,11 @@
};
}
- private CompletionProvider editKeywordCompletion() {
+ private CompletionProvider snippetKeywordCompletion(Supplier<List<? extends Snippet>> snippetsSupplier) {
return (code, cursor, anchor) -> {
List<Suggestion> result = new ArrayList<>();
result.addAll(KEYWORD_COMPLETION_PROVIDER.completionSuggestions(code, cursor, anchor));
- result.addAll(editCompletion().completionSuggestions(code, cursor, anchor));
+ result.addAll(snippetCompletion(snippetsSupplier).completionSuggestions(code, cursor, anchor));
return result;
};
}
@@ -963,18 +962,51 @@
};
}
+ // Snippet lists
+
+ List<Snippet> allSnippets() {
+ return state.snippets();
+ }
+
+ List<Snippet> dropableSnippets() {
+ return state.snippets().stream()
+ .filter(sn -> state.status(sn).isActive)
+ .collect(toList());
+ }
+
+ List<VarSnippet> allVarSnippets() {
+ return state.snippets().stream()
+ .filter(sn -> sn.kind() == Snippet.Kind.VAR)
+ .map(sn -> (VarSnippet) sn)
+ .collect(toList());
+ }
+
+ List<MethodSnippet> allMethodSnippets() {
+ return state.snippets().stream()
+ .filter(sn -> sn.kind() == Snippet.Kind.METHOD)
+ .map(sn -> (MethodSnippet) sn)
+ .collect(toList());
+ }
+
+ List<TypeDeclSnippet> allTypeSnippets() {
+ return state.snippets().stream()
+ .filter(sn -> sn.kind() == Snippet.Kind.TYPE_DECL)
+ .map(sn -> (TypeDeclSnippet) sn)
+ .collect(toList());
+ }
+
// Table of commands -- with command forms, argument kinds, helpKey message, implementation, ...
{
registerCommand(new Command("/list",
arg -> cmdList(arg),
- editKeywordCompletion()));
+ snippetKeywordCompletion(this::allSnippets)));
registerCommand(new Command("/edit",
arg -> cmdEdit(arg),
- editCompletion()));
+ snippetCompletion(this::allSnippets)));
registerCommand(new Command("/drop",
arg -> cmdDrop(arg),
- editCompletion(),
+ snippetCompletion(this::dropableSnippets),
CommandKind.REPLAY));
registerCommand(new Command("/save",
arg -> cmdSave(arg),
@@ -983,14 +1015,14 @@
arg -> cmdOpen(arg),
FILE_COMPLETION_PROVIDER));
registerCommand(new Command("/vars",
- arg -> cmdVars(),
- EMPTY_COMPLETION_PROVIDER));
+ arg -> cmdVars(arg),
+ snippetKeywordCompletion(this::allVarSnippets)));
registerCommand(new Command("/methods",
- arg -> cmdMethods(),
- EMPTY_COMPLETION_PROVIDER));
- registerCommand(new Command("/classes",
- arg -> cmdClasses(),
- EMPTY_COMPLETION_PROVIDER));
+ arg -> cmdMethods(arg),
+ snippetKeywordCompletion(this::allMethodSnippets)));
+ registerCommand(new Command("/types",
+ arg -> cmdTypes(arg),
+ snippetKeywordCompletion(this::allTypeSnippets)));
registerCommand(new Command("/imports",
arg -> cmdImports(),
EMPTY_COMPLETION_PROVIDER));
@@ -1312,7 +1344,7 @@
/**
* Avoid parameterized varargs possible heap pollution warning.
*/
- private interface SnippetPredicate extends Predicate<Snippet> { }
+ private interface SnippetPredicate<T extends Snippet> extends Predicate<T> { }
/**
* Apply filters to a stream until one that is non-empty is found.
@@ -1322,10 +1354,11 @@
* @param filters Filters to attempt
* @return The non-empty filtered Stream, or null
*/
- private static Stream<Snippet> nonEmptyStream(Supplier<Stream<Snippet>> supplier,
- SnippetPredicate... filters) {
- for (SnippetPredicate filt : filters) {
- Iterator<Snippet> iterator = supplier.get().filter(filt).iterator();
+ @SafeVarargs
+ private static <T extends Snippet> Stream<T> nonEmptyStream(Supplier<Stream<T>> supplier,
+ SnippetPredicate<T>... filters) {
+ for (SnippetPredicate<T> filt : filters) {
+ Iterator<T> iterator = supplier.get().filter(filt).iterator();
if (iterator.hasNext()) {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
}
@@ -1354,11 +1387,27 @@
* Convert a user argument to a Stream of snippets referenced by that argument
* (or lack of argument).
*
- * @param arg The user's argument to the command, maybe be the empty string
+ * @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<Snippet> argToSnippets(String arg, boolean allowAll) {
- List<Snippet> snippets = state.snippets();
+ private <T extends Snippet> Stream<T> argToSnippets(List<T> 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).
+ *
+ * @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
+ */
+ private <T extends Snippet> Stream<T> argToSnippets(List<T> snippets,
+ Predicate<Snippet> defFilter, String arg, boolean allowAll) {
if (allowAll && arg.equals("all")) {
// all snippets including start-up, failed, and overwritten
return snippets.stream();
@@ -1369,9 +1418,9 @@
} else if (arg.isEmpty()) {
// Default is all active user snippets
return snippets.stream()
- .filter(this::mainActive);
+ .filter(defFilter);
} else {
- Stream<Snippet> result =
+ Stream<T> result =
nonEmptyStream(
() -> snippets.stream(),
// look for active user declarations matching the name
@@ -1385,12 +1434,39 @@
}
}
+ /**
+ * Convert a user argument to a Stream of snippets referenced by that
+ * argument, printing an informative message if no matches. Allow 'all' and
+ * 'start'.
+ *
+ * @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
+ * @return a Stream of referenced snippets or null if no matches to specific
+ * arg
+ */
+ private <T extends Snippet> Stream<T> argToSnippetsWithMessage(List<T> snippets,
+ Predicate<Snippet> defFilter, String arg, String cmd) {
+ Stream<T> 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);
+ } else {
+ hardmsg("jshell.msg.no.active");
+ }
+ }
+ return stream;
+ }
+
private boolean cmdDrop(String arg) {
if (arg.isEmpty()) {
errormsg("jshell.err.drop.arg");
return false;
}
- Stream<Snippet> stream = argToSnippets(arg, false);
+ Stream<Snippet> stream = argToSnippets(dropableSnippets(), arg, false);
if (stream == null) {
errormsg("jshell.err.def.or.id.not.found", arg);
fluffmsg("jshell.msg.see.classes.etc");
@@ -1417,10 +1493,9 @@
}
private boolean cmdEdit(String arg) {
- Stream<Snippet> stream = argToSnippets(arg, true);
+ Stream<Snippet> stream = argToSnippetsWithMessage(state.snippets(),
+ this::mainActive, arg, "/edit");
if (stream == null) {
- errormsg("jshell.err.def.or.id.not.found", arg);
- fluffmsg("jshell.msg.see.classes.etc");
return false;
}
Set<String> srcSet = new LinkedHashSet<>();
@@ -1523,15 +1598,9 @@
if (arg.equals("history")) {
return cmdHistory();
}
- Stream<Snippet> stream = argToSnippets(arg, true);
+ Stream<Snippet> stream = argToSnippetsWithMessage(state.snippets(),
+ this::mainActive, arg, "/list");
if (stream == null) {
- errormsg("jshell.err.def.or.id.not.found", arg);
- // Check if there are any definitions at all
- if (argToSnippets("", false).iterator().hasNext()) {
- fluffmsg("jshell.msg.try.list.without.args");
- } else {
- hardmsg("jshell.msg.no.active");
- }
return false;
}
@@ -1662,7 +1731,7 @@
} else if (saveStart) {
writer.append(DEFAULT_STARTUP);
} else {
- Stream<Snippet> stream = argToSnippets(saveAll, true);
+ Stream<Snippet> stream = argToSnippets(state.snippets(), saveAll, true);
if (stream != null) {
for (Snippet sn : stream.collect(toList())) {
writer.write(sn.source());
@@ -1680,25 +1749,42 @@
return true;
}
- private boolean cmdVars() {
- for (VarSnippet vk : state.variables()) {
+ private boolean cmdVars(String arg) {
+ Stream<VarSnippet> stream = argToSnippetsWithMessage(allVarSnippets(),
+ this::isActive, arg, "/vars");
+ if (stream == null) {
+ return false;
+ }
+ stream.forEachOrdered(vk ->
+ {
String val = state.status(vk) == Status.VALID
? state.varValue(vk)
: "jshell.msg.vars.not.active";
hard(" %s %s = %s", vk.typeName(), vk.name(), val);
- }
+ });
return true;
}
- private boolean cmdMethods() {
- for (MethodSnippet mk : state.methods()) {
- hard(" %s %s", mk.name(), mk.signature());
+ private boolean cmdMethods(String arg) {
+ Stream<MethodSnippet> stream = argToSnippetsWithMessage(allMethodSnippets(),
+ this::isActive, arg, "/methods");
+ if (stream == null) {
+ return false;
}
+ stream.forEachOrdered(mk
+ -> hard(" %s %s", mk.name(), mk.signature())
+ );
return true;
}
- private boolean cmdClasses() {
- for (TypeDeclSnippet ck : state.types()) {
+ private boolean cmdTypes(String arg) {
+ Stream<TypeDeclSnippet> stream = argToSnippetsWithMessage(allTypeSnippets(),
+ this::isActive, arg, "/types");
+ if (stream == null) {
+ return false;
+ }
+ stream.forEachOrdered(ck
+ -> {
String kind;
switch (ck.subKind()) {
case INTERFACE_SUBKIND:
@@ -1719,7 +1805,7 @@
break;
}
hard(" %s %s", kind, ck.name());
- }
+ });
return true;
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Mon May 16 21:25:44 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Mon May 16 21:46:32 2016 -0700
@@ -37,8 +37,8 @@
Restore definitions with: /reload restore
jshell.msg.use.one.of = Use one of: {0}
-jshell.err.def.or.id.not.found = No definition or id found named: {0}
-jshell.msg.see.classes.etc = See /classes, /methods, /vars, or /list
+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.
@@ -57,7 +57,7 @@
jshell.err.cant.launch.editor = Cannot launch editor -- unexpected exception: {0}
jshell.msg.try.set.editor = Try /set editor to use external editor.
-jshell.msg.try.list.without.args = Try ''/list'' without arguments.
+jshell.msg.try.command.without.args = Try ''{0}'' without arguments.
jshell.msg.no.active = There are no active definitions.
jshell.msg.resetting = Resetting...
@@ -151,7 +151,7 @@
\ -version Version information\n
help.list.summary = list the source you have typed
-help.list.args = [all|start|<name or id>]
+help.list.args = [<name or id>|all|start]
help.list =\
Show the source of snippets, prefaced with the snippet id.\n\
\n\
@@ -214,19 +214,52 @@
Read the specified file as jshell input.
help.vars.summary = list the declared variables and their values
-help.vars.args =
+help.vars.args = [<name or id>|all|start]
help.vars =\
-List the type, name, and value of the current active jshell variables.
+List the type, name, and value of jshell variables.\n\
+\n\
+/vars\n\t\
+ List the type, name, and value of the current active jshell variables\n\n\
+/vars <name>\n\t\
+ List jshell variables with the specified name (preference for active variables)\n\n\
+/vars <id>\n\t\
+ List the jshell variable with the specified snippet id\n\n\
+/vars start\n\t\
+ List the automatically added start-up jshell variables\n\n\
+/vars all\n\t\
+ List all jshell variables including failed, overwritten, dropped, and start-up
help.methods.summary = list the declared methods and their signatures
-help.methods.args =
+help.methods.args = [<name or id>|all|start]
help.methods =\
-List the name, parameter types, and return type of the current active jshell methods.
+List the name, parameter types, and return type of jshell methods.\n\
+\n\
+/methods\n\t\
+ List the name, parameter types, and return type of the current active jshell methods\n\n\
+/methods <name>\n\t\
+ List jshell methods with the specified name (preference for active methods)\n\n\
+/methods <id>\n\t\
+ List the jshell method with the specified snippet id\n\n\
+/methods start\n\t\
+ List the automatically added start-up jshell methods\n\n\
+/methods all\n\t\
+ List all snippets including failed, overwritten, dropped, and start-up
-help.classes.summary = list the declared classes
-help.classes.args =
-help.classes =\
-List the current active jshell classes, interfaces, and enums.
+help.types.summary = list the declared types
+help.types.args =[<name or id>|all|start]
+help.types =\
+List jshell classes, interfaces, and enums.\n\
+\n\
+/types\n\t\
+ List the current active jshell classes, interfaces, and enums.\n\n\
+/types <name>\n\t\
+ List jshell types with the specified name (preference for active types)\n\n\
+/types <id>\n\t\
+ List the jshell type with the specified snippet id\n\n\
+/types start\n\t\
+ List the automatically added start-up jshell types\n\n\
+/types all\n\t\
+ List all jshell types including failed, overwritten, dropped, and start-up
help.imports.summary = list the imported items
help.imports.args =
@@ -304,7 +337,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|format ...
+help.set.args = editor|start|feedback|newmode|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\
--- a/langtools/test/jdk/jshell/CommandCompletionTest.java Mon May 16 21:25:44 2016 -0700
+++ b/langtools/test/jdk/jshell/CommandCompletionTest.java Mon May 16 21:46:32 2016 -0700
@@ -53,7 +53,7 @@
public void testCommand() {
assertCompletion("/deb|", false);
- assertCompletion("/c|", false, "/classes ", "/classpath ");
+ assertCompletion("/re|", false, "/reload ", "/reset ");
assertCompletion("/h|", false, "/help ", "/history ");
}
--- a/langtools/test/jdk/jshell/EditorTestBase.java Mon May 16 21:25:44 2016 -0700
+++ b/langtools/test/jdk/jshell/EditorTestBase.java Mon May 16 21:46:32 2016 -0700
@@ -142,7 +142,7 @@
exit();
loadClass(true, "enum A {}", "enum", "A");
}),
- a -> assertCommandCheckOutput(a, "/classes", assertClasses())
+ a -> assertCommandCheckOutput(a, "/types", assertClasses())
);
}
@@ -161,7 +161,7 @@
exit();
loadClass(true, "enum A {}", "enum", "A");
}),
- a -> assertCommandCheckOutput(a, "/classes", assertClasses())
+ a -> assertCommandCheckOutput(a, "/types", assertClasses())
);
}
--- a/langtools/test/jdk/jshell/ReplToolTesting.java Mon May 16 21:25:44 2016 -0700
+++ b/langtools/test/jdk/jshell/ReplToolTesting.java Mon May 16 21:46:32 2016 -0700
@@ -70,6 +70,9 @@
new MethodInfo("void printf(String format, Object... args) { System.out.printf(format, args); }",
"(String,Object...)void", "printf"))
.collect(toList());
+ final static List<String> START_UP_CMD_METHOD = Stream.of(
+ "| printf (String,Object...)void")
+ .collect(toList());
final static List<String> START_UP = Collections.unmodifiableList(
Stream.concat(START_UP_IMPORTS.stream(), START_UP_METHODS.stream())
.map(s -> s.getSource())
--- a/langtools/test/jdk/jshell/ToolBasicTest.java Mon May 16 21:25:44 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolBasicTest.java Mon May 16 21:46:32 2016 -0700
@@ -118,9 +118,9 @@
(a) -> assertCommand(a, "class A {" + s, ""),
interrupt,
(a) -> assertCommand(a, "class A {}\u0003", ""),
- (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
(a) -> assertClass(a, "interface A {}", "interface", "A"),
- (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
(a) -> assertCommand(a, "import java.util.stream." + s, ""),
interrupt,
(a) -> assertCommand(a, "import java.util.stream.\u0003", ""),
@@ -338,13 +338,13 @@
(a) -> assertMethod(a, "void f() { }", "()void", "f"),
(a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
(a) -> assertClass(a, "class A { }", "class", "A"),
- (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
(a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
(a) -> assertCommandCheckOutput(a, "/imports", assertImports()),
(a) -> assertReset(a, "/reset"),
(a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
(a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
- (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
(a) -> assertCommandCheckOutput(a, "/imports", assertImports())
);
}
@@ -369,7 +369,7 @@
loadClass(a, "class A { public String toString() { return \"A\"; } }",
"class", "A");
loadImport(a, "import java.util.stream.*;", "", "java.util.stream.*");
- assertCommandCheckOutput(a, "/classes", assertClasses());
+ assertCommandCheckOutput(a, "/types", assertClasses());
},
(a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
(a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
@@ -451,7 +451,7 @@
loadVariable(a, "double", "b", "10.0", "10.0");
loadMethod(a, "void f() {}", "()void", "f");
loadImport(a, "import java.util.stream.*;", "", "java.util.stream.*");
- assertCommandCheckOutput(a, "/classes", assertClasses());
+ assertCommandCheckOutput(a, "/types", assertClasses());
},
(a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
(a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
--- a/langtools/test/jdk/jshell/ToolReloadTest.java Mon May 16 21:25:44 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolReloadTest.java Mon May 16 21:46:32 2016 -0700
@@ -107,7 +107,7 @@
"-: /drop A\n"),
a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
a -> assertCommandCheckOutput(a, "/methods", assertMethods()),
- a -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ a -> assertCommandCheckOutput(a, "/types", assertClasses()),
a -> assertCommandCheckOutput(a, "/imports", assertImports())
);
}
@@ -124,7 +124,7 @@
"| Restarting and restoring state."),
a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
a -> assertCommandCheckOutput(a, "/methods", assertMethods()),
- a -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ a -> assertCommandCheckOutput(a, "/types", assertClasses()),
a -> assertCommandCheckOutput(a, "/imports", assertImports())
);
}
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java Mon May 16 21:25:44 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java Mon May 16 21:46:32 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8153716 8143955 8151754 8150382
+ * @bug 8153716 8143955 8151754 8150382 8153920
* @summary Simple jshell tool tests
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -101,22 +101,22 @@
);
}
- public void defineClasses() {
+ public void defineTypes() {
test(
(a) -> assertCommandCheckOutput(a, "/list", assertList()),
- (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
(a) -> assertClass(a, "class A { }", "class", "A"),
(a) -> assertCommandCheckOutput(a, "/list", assertList()),
- (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
(a) -> assertClass(a, "interface A { }", "interface", "A"),
(a) -> assertCommandCheckOutput(a, "/list", assertList()),
- (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
(a) -> assertClass(a, "enum A { }", "enum", "A"),
(a) -> assertCommandCheckOutput(a, "/list", assertList()),
- (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
(a) -> assertClass(a, "@interface A { }", "@interface", "A"),
(a) -> assertCommandCheckOutput(a, "/list", assertList()),
- (a) -> assertCommandCheckOutput(a, "/classes", assertClasses())
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses())
);
}
@@ -211,7 +211,7 @@
a -> dropImport(a, "/drop 4", "import java.util.stream.*", ""),
a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
a -> assertCommandCheckOutput(a, "/methods", assertMethods()),
- a -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ a -> assertCommandCheckOutput(a, "/types", assertClasses()),
a -> assertCommandCheckOutput(a, "/imports", assertImports())
);
test(false, new String[]{"-nostartup"},
@@ -223,15 +223,15 @@
a -> dropClass(a, "/drop A", "class A", "| dropped class A"),
a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
a -> assertCommandCheckOutput(a, "/methods", assertMethods()),
- a -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ a -> assertCommandCheckOutput(a, "/types", assertClasses()),
a -> assertCommandCheckOutput(a, "/imports", assertImports())
);
}
public void testDropNegative() {
test(false, new String[]{"-nostartup"},
- a -> assertCommandOutputStartsWith(a, "/drop 0", "| No definition or id found named: 0"),
- a -> assertCommandOutputStartsWith(a, "/drop a", "| No definition or id found named: a"),
+ 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 -> assertCommandCheckOutput(a, "/drop",
assertStartsWith("| In the /drop argument, please specify an import, variable, method, or class to drop.")),
a -> assertVariable(a, "int", "a"),
@@ -253,7 +253,7 @@
a -> assertCommandCheckOutput(a, "/drop a", check),
a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
a -> assertCommandCheckOutput(a, "/methods", assertMethods()),
- a -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ a -> assertCommandCheckOutput(a, "/types", assertClasses()),
a -> assertCommandCheckOutput(a, "/imports", assertImports())
);
test(
@@ -299,7 +299,10 @@
// Check that each line of output contains the corresponding string from the list
private void checkLineToList(String in, List<String> match) {
- String[] res = in.trim().split("\n");
+ String trimmed = in.trim();
+ String[] res = trimmed.isEmpty()
+ ? new String[0]
+ : trimmed.split("\n");
assertEquals(res.length, match.size(), "Got: " + Arrays.asList(res));
for (int i = 0; i < match.size(); ++i) {
assertTrue(res[i].contains(match.get(i)));
@@ -314,7 +317,7 @@
a -> assertCommandCheckOutput(a, "/list all",
s -> checkLineToList(s, START_UP)),
a -> assertCommandOutputStartsWith(a, "/list " + arg,
- "| No definition or id found named: " + arg),
+ "| No applicable definition or id found named: " + arg),
a -> assertVariable(a, "int", "aardvark"),
a -> assertCommandOutputContains(a, "/list aardvark", "aardvark"),
a -> assertCommandCheckOutput(a, "/list start",
@@ -324,10 +327,118 @@
a -> assertCommandCheckOutput(a, "/list printf",
s -> assertTrue(s.contains("void printf"))),
a -> assertCommandOutputStartsWith(a, "/list " + arg,
- "| No definition or id found named: " + arg)
+ "| No applicable definition or id found named: " + arg)
+ );
+ }
+
+ public void testVarsArgs() {
+ String arg = "qqqq";
+ List<String> startVarList = new ArrayList<>();
+ test(
+ a -> assertCommandCheckOutput(a, "/vars all",
+ s -> checkLineToList(s, startVarList)),
+ a -> assertCommandOutputStartsWith(a, "/vars " + arg,
+ "| No applicable definition or id found named: " + 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 -> 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)
);
}
+ public void testMethodsArgs() {
+ String arg = "qqqq";
+ List<String> startMethodList = new ArrayList<>(START_UP_CMD_METHOD);
+ test(
+ a -> assertCommandCheckOutput(a, "/methods all",
+ s -> checkLineToList(s, startMethodList)),
+ a -> assertCommandCheckOutput(a, "/methods start",
+ s -> checkLineToList(s, startMethodList)),
+ a -> assertCommandCheckOutput(a, "/methods printf",
+ s -> checkLineToList(s, startMethodList)),
+ a -> assertCommandCheckOutput(a, "/methods",
+ s -> checkLineToList(s, startMethodList)),
+ a -> assertCommandOutputStartsWith(a, "/methods " + arg,
+ "| No applicable definition or id found named: " + 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),
+ a -> assertCommandOutputStartsWith(a, "/methods aardvark",
+ "| No applicable definition or id found named: aardvark"),
+ a -> assertCommandCheckOutput(a, "/methods start",
+ s -> checkLineToList(s, startMethodList)),
+ a -> assertCommandCheckOutput(a, "/methods printf",
+ s -> checkLineToList(s, startMethodList)),
+ a -> assertCommandOutputStartsWith(a, "/methods g",
+ "| g ()void"),
+ a -> assertCommandOutputStartsWith(a, "/methods f",
+ "| f ()int\n" +
+ "| f (int)void")
+ );
+ }
+
+ public void testTypesArgs() {
+ String arg = "qqqq";
+ List<String> startTypeList = new ArrayList<>();
+ test(
+ a -> assertCommandCheckOutput(a, "/types all",
+ s -> checkLineToList(s, startTypeList)),
+ a -> assertCommandCheckOutput(a, "/types start",
+ s -> checkLineToList(s, startTypeList)),
+ a -> assertCommandOutputStartsWith(a, "/types " + arg,
+ "| No applicable definition or id found named: " + arg),
+ a -> assertVariable(a, "int", "aardvark"),
+ (a) -> assertClass(a, "class A { }", "class", "A"),
+ (a) -> assertClass(a, "interface A { }", "interface", "A"),
+ a -> assertCommandOutputStartsWith(a, "/types all",
+ "| class A\n" +
+ "| 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 -> assertCommandOutputStartsWith(a, "/types A",
+ "| interface A"),
+ a -> assertCommandOutputStartsWith(a, "/types E",
+ "| enum E"),
+ a -> assertCommandOutputStartsWith(a, "/types B",
+ "| @interface B"),
+ a -> assertCommandOutputStartsWith(a, "/types " + arg,
+ "| No applicable definition or id found named: " + arg),
+ a -> assertCommandCheckOutput(a, "/types start",
+ s -> checkLineToList(s, startTypeList))
+ );
+ }
+ public void defineClasses() {
+ test(
+ (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
+ (a) -> assertClass(a, "class A { }", "class", "A"),
+ (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
+ (a) -> assertClass(a, "interface A { }", "interface", "A"),
+ (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
+ (a) -> assertClass(a, "enum A { }", "enum", "A"),
+ (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
+ (a) -> assertClass(a, "@interface A { }", "@interface", "A"),
+ (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+ (a) -> assertCommandCheckOutput(a, "/types", assertClasses())
+ );
+ }
public void testCommandPrefix() {
test(a -> assertCommandCheckOutput(a, "/s",
assertStartsWith("| Command: '/s' is ambiguous: /save, /set")),