# HG changeset patch # User rfield # Date 1470808849 25200 # Node ID 0318f4e75c6dbaf9175502e61c2554c9da9b336c # Parent 96a1226aca18e51bf5a4fc202ffbed283133bad8 8143964: JShell API: convert query responses to Stream instead of List Reviewed-by: psandoz, shinyafox diff -r 96a1226aca18 -r 0318f4e75c6d 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 Tue Aug 09 13:22:57 2016 -0700 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Tue Aug 09 23:00:49 2016 -0700 @@ -973,10 +973,10 @@ p.getFileName().toString().endsWith(".jar")); } - private CompletionProvider snippetCompletion(Supplier> snippetsSupplier) { + private CompletionProvider snippetCompletion(Supplier> snippetsSupplier) { return (prefix, cursor, anchor) -> { anchor[0] = 0; - return snippetsSupplier.get() .stream() + return snippetsSupplier.get() .flatMap(k -> (k instanceof DeclarationSnippet) ? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name()) : Stream.of(String.valueOf(k.id()))) @@ -986,7 +986,7 @@ }; } - private CompletionProvider snippetKeywordCompletion(Supplier> snippetsSupplier) { + private CompletionProvider snippetKeywordCompletion(Supplier> snippetsSupplier) { return (code, cursor, anchor) -> { List result = new ArrayList<>(); result.addAll(KEYWORD_COMPLETION_PROVIDER.completionSuggestions(code, cursor, anchor)); @@ -1020,36 +1020,32 @@ // Snippet lists - List allSnippets() { + Stream allSnippets() { return state.snippets(); } - List dropableSnippets() { - return state.snippets().stream() + Stream dropableSnippets() { + return state.snippets() .filter(sn -> state.status(sn).isActive() && sn instanceof PersistentSnippet) - .map(sn -> (PersistentSnippet) sn) - .collect(toList()); + .map(sn -> (PersistentSnippet) sn); } - List allVarSnippets() { - return state.snippets().stream() + Stream allVarSnippets() { + return state.snippets() .filter(sn -> sn.kind() == Snippet.Kind.VAR) - .map(sn -> (VarSnippet) sn) - .collect(toList()); + .map(sn -> (VarSnippet) sn); } - List allMethodSnippets() { - return state.snippets().stream() + Stream allMethodSnippets() { + return state.snippets() .filter(sn -> sn.kind() == Snippet.Kind.METHOD) - .map(sn -> (MethodSnippet) sn) - .collect(toList()); + .map(sn -> (MethodSnippet) sn); } - List allTypeSnippets() { - return state.snippets().stream() + Stream allTypeSnippets() { + return state.snippets() .filter(sn -> sn.kind() == Snippet.Kind.TYPE_DECL) - .map(sn -> (TypeDeclSnippet) sn) - .collect(toList()); + .map(sn -> (TypeDeclSnippet) sn); } // Table of commands -- with command forms, argument kinds, helpKey message, implementation, ... @@ -1549,7 +1545,7 @@ * string * @return a Stream of referenced snippets or null if no matches are found */ - private Stream argsOptionsToSnippets(List snippets, + private Stream argsOptionsToSnippets(Supplier> snippetSupplier, Predicate defFilter, String rawargs, String cmd) { ArgTokenizer at = new ArgTokenizer(cmd, rawargs.trim()); at.allowedOptions("-all", "-start"); @@ -1571,38 +1567,38 @@ } if (at.hasOption("-all")) { // all snippets including start-up, failed, and overwritten - return snippets.stream(); + return snippetSupplier.get(); } if (at.hasOption("-start")) { // start-up snippets - return snippets.stream() + return snippetSupplier.get() .filter(this::inStartUp); } if (args.isEmpty()) { // Default is all active user snippets - return snippets.stream() + return snippetSupplier.get() .filter(defFilter); } - return argsToSnippets(snippets, args); + return argsToSnippets(snippetSupplier, args); } /** * Convert user arguments to a Stream of snippets referenced by those * arguments. * - * @param snippets the base list of possible snippets + * @param snippetSupplier the base list of possible snippets * @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 argsToSnippets(List snippets, + private Stream argsToSnippets(Supplier> snippetSupplier, List args) { Stream result = null; for (String arg : args) { // Find the best match - Stream st = layeredSnippetSearch(snippets, arg); + Stream st = layeredSnippetSearch(snippetSupplier, arg); if (st == null) { - Stream est = layeredSnippetSearch(state.snippets(), arg); + Stream est = layeredSnippetSearch(state::snippets, arg); if (est == null) { errormsg("jshell.err.no.such.snippets", arg); } else { @@ -1620,10 +1616,10 @@ return result; } - private Stream layeredSnippetSearch(List snippets, String arg) { + private Stream layeredSnippetSearch(Supplier> snippetSupplier, String arg) { return nonEmptyStream( // the stream supplier - () -> snippets.stream(), + snippetSupplier, // look for active user declarations matching the name sn -> isActive(sn) && matchingDeclaration(sn, arg), // else, look for any declarations matching the name @@ -1648,7 +1644,7 @@ errormsg("jshell.err.drop.arg"); return false; } - Stream stream = argsToSnippets(dropableSnippets(), args); + Stream stream = argsToSnippets(this::dropableSnippets, args); if (stream == null) { // Snippet not found. Error already printed fluffmsg("jshell.msg.see.classes.etc"); @@ -1670,7 +1666,7 @@ } private boolean cmdEdit(String arg) { - Stream stream = argsOptionsToSnippets(state.snippets(), + Stream stream = argsOptionsToSnippets(state::snippets, this::mainActive, arg, "/edit"); if (stream == null) { return false; @@ -1775,7 +1771,7 @@ if (arg.length() >= 2 && "-history".startsWith(arg)) { return cmdHistory(); } - Stream stream = argsOptionsToSnippets(state.snippets(), + Stream stream = argsOptionsToSnippets(state::snippets, this::mainActive, arg, "/list"); if (stream == null) { return false; @@ -1896,13 +1892,12 @@ } else if (at.hasOption("-start")) { writer.append(startup); } else { - List sns = at.hasOption("-all") + String sources = (at.hasOption("-all") ? state.snippets() - : state.snippets().stream().filter(this::mainActive).collect(toList()); - for (Snippet sn : sns) { - writer.write(sn.source()); - writer.write("\n"); - } + : state.snippets().filter(this::mainActive)) + .map(Snippet::source) + .collect(Collectors.joining("\n")); + writer.write(sources); } } catch (FileNotFoundException e) { errormsg("jshell.err.file.not.found", "/save", filename, e.getMessage()); @@ -1915,7 +1910,7 @@ } private boolean cmdVars(String arg) { - Stream stream = argsOptionsToSnippets(allVarSnippets(), + Stream stream = argsOptionsToSnippets(this::allVarSnippets, this::isActive, arg, "/vars"); if (stream == null) { return false; @@ -1931,7 +1926,7 @@ } private boolean cmdMethods(String arg) { - Stream stream = argsOptionsToSnippets(allMethodSnippets(), + Stream stream = argsOptionsToSnippets(this::allMethodSnippets, this::isActive, arg, "/methods"); if (stream == null) { return false; @@ -1943,7 +1938,7 @@ } private boolean cmdTypes(String arg) { - Stream stream = argsOptionsToSnippets(allTypeSnippets(), + Stream stream = argsOptionsToSnippets(this::allTypeSnippets, this::isActive, arg, "/types"); if (stream == null) { return false; @@ -1982,7 +1977,7 @@ } private boolean cmdUseHistoryEntry(int index) { - List keys = state.snippets(); + List keys = state.snippets().collect(toList()); if (index < 0) index += keys.size(); else @@ -2012,7 +2007,7 @@ } private boolean rerunHistoryEntryById(String id) { - Optional snippet = state.snippets().stream() + Optional snippet = state.snippets() .filter(s -> s.id().equals(id)) .findFirst(); return snippet.map(s -> { @@ -2135,7 +2130,7 @@ debug("Event with null key: %s", ste); return false; } - List diagnostics = state.diagnostics(sn); + List diagnostics = state.diagnostics(sn).collect(toList()); String source = sn.source(); if (ste.causeSnippet() == null) { // main event @@ -2212,7 +2207,7 @@ //where void printUnresolvedException(UnresolvedReferenceException ex) { DeclarationSnippet corralled = ex.getSnippet(); - List otherErrors = errorsOnly(state.diagnostics(corralled)); + List otherErrors = errorsOnly(state.diagnostics(corralled).collect(toList())); new DisplayEvent(corralled, state.status(corralled), FormatAction.USED, true, null, otherErrors) .displayDeclarationAndValue(); } @@ -2280,13 +2275,13 @@ for (Diag d : errors) { displayDiagnostics(sn.source(), d, errorLines); } - int unresolvedCount; + long unresolvedCount; if (sn instanceof DeclarationSnippet && (status == Status.RECOVERABLE_DEFINED || status == Status.RECOVERABLE_NOT_DEFINED)) { resolution = (status == Status.RECOVERABLE_NOT_DEFINED) ? FormatResolve.NOTDEFINED : FormatResolve.DEFINED; unresolved = unresolved((DeclarationSnippet) sn); - unresolvedCount = state.unresolvedDependencies((DeclarationSnippet) sn).size(); + unresolvedCount = state.unresolvedDependencies((DeclarationSnippet) sn).count(); } else { resolution = FormatResolve.OK; unresolved = ""; @@ -2305,7 +2300,7 @@ } private String unresolved(DeclarationSnippet key) { - List unr = state.unresolvedDependencies(key); + List unr = state.unresolvedDependencies(key).collect(toList()); StringBuilder sb = new StringBuilder(); int fromLast = unr.size(); if (fromLast > 0) { diff -r 96a1226aca18 -r 0318f4e75c6d langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Tue Aug 09 13:22:57 2016 -0700 +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Tue Aug 09 23:00:49 2016 -0700 @@ -43,6 +43,7 @@ import java.util.function.Consumer; import java.util.function.Supplier; +import java.util.stream.Stream; import jdk.internal.jshell.debug.InternalDebugControl; import jdk.jshell.Snippet.Status; import jdk.jshell.execution.JDIDefaultExecutionControl; @@ -504,9 +505,9 @@ * @return the snippets for all current snippets in id order. * @throws IllegalStateException if this JShell instance is closed. */ - public List snippets() throws IllegalStateException { + public Stream snippets() throws IllegalStateException { checkIfAlive(); - return Collections.unmodifiableList(maps.snippetList()); + return maps.snippetList().stream(); } /** @@ -518,11 +519,10 @@ * @return the active declared variables. * @throws IllegalStateException if this JShell instance is closed. */ - public List variables() throws IllegalStateException { - return snippets().stream() + public Stream variables() throws IllegalStateException { + return snippets() .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.VAR) - .map(sn -> (VarSnippet) sn) - .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + .map(sn -> (VarSnippet) sn); } /** @@ -534,11 +534,10 @@ * @return the active declared methods. * @throws IllegalStateException if this JShell instance is closed. */ - public List methods() throws IllegalStateException { - return snippets().stream() + public Stream methods() throws IllegalStateException { + return snippets() .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.METHOD) - .map(sn -> (MethodSnippet)sn) - .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + .map(sn -> (MethodSnippet)sn); } /** @@ -550,11 +549,10 @@ * @return the active declared type declarations. * @throws IllegalStateException if this JShell instance is closed. */ - public List types() throws IllegalStateException { - return snippets().stream() + public Stream types() throws IllegalStateException { + return snippets() .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.TYPE_DECL) - .map(sn -> (TypeDeclSnippet) sn) - .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + .map(sn -> (TypeDeclSnippet) sn); } /** @@ -566,11 +564,10 @@ * @return the active declared import declarations. * @throws IllegalStateException if this JShell instance is closed. */ - public List imports() throws IllegalStateException { - return snippets().stream() + public Stream imports() throws IllegalStateException { + return snippets() .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.IMPORT) - .map(sn -> (ImportSnippet) sn) - .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + .map(sn -> (ImportSnippet) sn); } /** @@ -598,8 +595,8 @@ * @throws IllegalArgumentException if the snippet is not associated with * this {@code JShell} instance. */ - public List diagnostics(Snippet snippet) { - return Collections.unmodifiableList(checkValidSnippet(snippet).diagnostics()); + public Stream diagnostics(Snippet snippet) { + return checkValidSnippet(snippet).diagnostics().stream(); } /** @@ -611,13 +608,13 @@ * {@code eval()} or {@code drop()} of another snippet causes * an update of a dependency. * @param snippet the declaration {@code Snippet} to look up - * @return the list of symbol names that are currently unresolvedDependencies. + * @return a stream of symbol names that are currently unresolvedDependencies. * @throws IllegalStateException if this {@code JShell} instance is closed. * @throws IllegalArgumentException if the snippet is not associated with * this {@code JShell} instance. */ - public List unresolvedDependencies(DeclarationSnippet snippet) { - return Collections.unmodifiableList(checkValidSnippet(snippet).unresolved()); + public Stream unresolvedDependencies(DeclarationSnippet snippet) { + return checkValidSnippet(snippet).unresolved().stream(); } /** diff -r 96a1226aca18 -r 0318f4e75c6d langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Tue Aug 09 13:22:57 2016 -0700 +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Tue Aug 09 23:00:49 2016 -0700 @@ -414,25 +414,29 @@ // types are the same. if so, consider it an overwrite replacement. private Status overwriteMatchingMethod(MethodSnippet msi) { String qpt = msi.qualifiedParameterTypes(); + List matching = state.methods() + .filter(sn -> + sn != null + && sn != msi + && sn.status().isActive() + && sn.name().equals(msi.name()) + && qpt.equals(sn.qualifiedParameterTypes())) + .collect(toList()); // Look through all methods for a method of the same name, with the // same computed qualified parameter types Status overwrittenStatus = null; - for (MethodSnippet sn : state.methods()) { - if (sn != null && sn != msi && sn.status().isActive() && sn.name().equals(msi.name())) { - if (qpt.equals(sn.qualifiedParameterTypes())) { - overwrittenStatus = sn.status(); - SnippetEvent se = new SnippetEvent( - sn, overwrittenStatus, OVERWRITTEN, - false, msi, null, null); - sn.setOverwritten(); - secondaryEvents.add(se); - state.debug(DBG_EVNT, - "Overwrite event #%d -- key: %s before: %s status: %s sig: %b cause: %s\n", - secondaryEvents.size(), se.snippet(), se.previousStatus(), - se.status(), se.isSignatureChange(), se.causeSnippet()); - } - } + for (MethodSnippet sn : matching) { + overwrittenStatus = sn.status(); + SnippetEvent se = new SnippetEvent( + sn, overwrittenStatus, OVERWRITTEN, + false, msi, null, null); + sn.setOverwritten(); + secondaryEvents.add(se); + state.debug(DBG_EVNT, + "Overwrite event #%d -- key: %s before: %s status: %s sig: %b cause: %s\n", + secondaryEvents.size(), se.snippet(), se.previousStatus(), + se.status(), se.isSignatureChange(), se.causeSnippet()); } return overwrittenStatus; } diff -r 96a1226aca18 -r 0318f4e75c6d langtools/test/jdk/jshell/ClassesTest.java --- a/langtools/test/jdk/jshell/ClassesTest.java Tue Aug 09 13:22:57 2016 -0700 +++ b/langtools/test/jdk/jshell/ClassesTest.java Tue Aug 09 23:00:49 2016 -0700 @@ -41,6 +41,7 @@ import org.testng.annotations.Test; import jdk.jshell.Diag; +import static java.util.stream.Collectors.toList; import static jdk.jshell.Snippet.Status.VALID; import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED; import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED; @@ -210,8 +211,8 @@ ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET)); ***/ // It is random which one it shows up in, but cyclic error should be there - List diagsA = getState().diagnostics(a); - List diagsB = getState().diagnostics(b); + List diagsA = getState().diagnostics(a).collect(toList()); + List diagsB = getState().diagnostics(b).collect(toList()); List diags; if (diagsA.isEmpty()) { diags = diagsB; diff -r 96a1226aca18 -r 0318f4e75c6d langtools/test/jdk/jshell/JShellQueryTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/jdk/jshell/JShellQueryTest.java Tue Aug 09 23:00:49 2016 -0700 @@ -0,0 +1,131 @@ +/* + * 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 8143964 + * @summary test queries to the JShell that return Streams + * @build KullaTesting + * @run testng JShellQueryTest + */ +import java.util.Set; +import java.util.stream.Stream; +import jdk.jshell.Snippet; +import org.testng.annotations.Test; + +import jdk.jshell.ImportSnippet; +import jdk.jshell.MethodSnippet; +import jdk.jshell.TypeDeclSnippet; +import jdk.jshell.VarSnippet; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toSet; +import static org.testng.Assert.assertEquals; + +@Test +public class JShellQueryTest extends KullaTesting { + + private void checkStreamMatch(Stream result, T... expected) { + Set sns = result.collect(toSet()); + Set exp = Stream.of(expected).collect(toSet()); + assertEquals(sns, exp); + } + + public void testSnippets() { + checkStreamMatch(getState().snippets()); + VarSnippet sx = varKey(assertEval("int x = 5;")); + VarSnippet sfoo = varKey(assertEval("String foo;")); + MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }")); + MethodSnippet svv = methodKey(assertEval("void vv() { }")); + checkStreamMatch(getState().snippets(), sx, sfoo, smm, svv); + TypeDeclSnippet sc = classKey(assertEval("class C { }")); + TypeDeclSnippet si = classKey(assertEval("interface I { }")); + ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;")); + checkStreamMatch(getState().snippets(), sx, sfoo, smm, svv, sc, si, simp); + } + + public void testVars() { + checkStreamMatch(getState().variables()); + VarSnippet sx = varKey(assertEval("int x = 5;")); + VarSnippet sfoo = varKey(assertEval("String foo;")); + MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }")); + MethodSnippet svv = methodKey(assertEval("void vv() { }")); + checkStreamMatch(getState().variables(), sx, sfoo); + TypeDeclSnippet sc = classKey(assertEval("class C { }")); + TypeDeclSnippet si = classKey(assertEval("interface I { }")); + ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;")); + checkStreamMatch(getState().variables(), sx, sfoo); + } + + public void testMethods() { + checkStreamMatch(getState().methods()); + VarSnippet sx = varKey(assertEval("int x = 5;")); + VarSnippet sfoo = varKey(assertEval("String foo;")); + MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }")); + MethodSnippet svv = methodKey(assertEval("void vv() { }")); + TypeDeclSnippet sc = classKey(assertEval("class C { }")); + TypeDeclSnippet si = classKey(assertEval("interface I { }")); + ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;")); + checkStreamMatch(getState().methods(), smm, svv); + } + + public void testTypes() { + checkStreamMatch(getState().types()); + VarSnippet sx = varKey(assertEval("int x = 5;")); + VarSnippet sfoo = varKey(assertEval("String foo;")); + MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }")); + MethodSnippet svv = methodKey(assertEval("void vv() { }")); + TypeDeclSnippet sc = classKey(assertEval("class C { }")); + TypeDeclSnippet si = classKey(assertEval("interface I { }")); + ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;")); + checkStreamMatch(getState().types(), sc, si); + } + + public void testImports() { + checkStreamMatch(getState().imports()); + VarSnippet sx = varKey(assertEval("int x = 5;")); + VarSnippet sfoo = varKey(assertEval("String foo;")); + MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }")); + MethodSnippet svv = methodKey(assertEval("void vv() { }")); + TypeDeclSnippet sc = classKey(assertEval("class C { }")); + TypeDeclSnippet si = classKey(assertEval("interface I { }")); + ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;")); + checkStreamMatch(getState().imports(), simp); + } + + public void testDiagnostics() { + Snippet sx = varKey(assertEval("int x = 5;")); + checkStreamMatch(getState().diagnostics(sx)); + Snippet broken = methodKey(assertEvalFail("int m() { blah(); return \"hello\"; }")); + String res = getState().diagnostics(broken) + .map(d -> d.getCode()) + .collect(joining("+")); + assertEquals(res, "compiler.err.cant.resolve.location.args+compiler.err.prob.found.req"); + } + + public void testUnresolvedDependencies() { + VarSnippet sx = varKey(assertEval("int x = 5;")); + checkStreamMatch(getState().unresolvedDependencies(sx)); + MethodSnippet unr = methodKey(getState().eval("void uu() { baz(); zips(); }")); + checkStreamMatch(getState().unresolvedDependencies(unr), "method zips()", "method baz()"); + } +} diff -r 96a1226aca18 -r 0318f4e75c6d langtools/test/jdk/jshell/KullaTesting.java --- a/langtools/test/jdk/jshell/KullaTesting.java Tue Aug 09 13:22:57 2016 -0700 +++ b/langtools/test/jdk/jshell/KullaTesting.java Tue Aug 09 23:00:49 2016 -0700 @@ -70,6 +70,7 @@ import org.testng.annotations.BeforeMethod; import jdk.jshell.Diag; +import static java.util.stream.Collectors.toList; import static jdk.jshell.Snippet.Status.*; import static org.testng.Assert.*; import static jdk.jshell.Snippet.SubKind.METHOD_SUBKIND; @@ -183,7 +184,7 @@ } public List assertUnresolvedDependencies(DeclarationSnippet key, int unresolvedSize) { - List unresolved = getState().unresolvedDependencies(key); + List unresolved = getState().unresolvedDependencies(key).collect(toList()); assertEquals(unresolved.size(), unresolvedSize, "Input: " + key.source() + ", checking unresolved: "); return unresolved; } @@ -202,8 +203,8 @@ SnippetEvent ste = events.get(0); DeclarationSnippet sn = ((UnresolvedReferenceException) ste.exception()).getSnippet(); assertEquals(sn.name(), name, "Given input: " + input + ", checking name"); - assertEquals(getState().unresolvedDependencies(sn).size(), unresolvedSize, "Given input: " + input + ", checking unresolved"); - assertEquals(getState().diagnostics(sn).size(), diagnosticsSize, "Given input: " + input + ", checking diagnostics"); + assertEquals(getState().unresolvedDependencies(sn).count(), unresolvedSize, "Given input: " + input + ", checking unresolved"); + assertEquals(getState().diagnostics(sn).count(), (long) diagnosticsSize, "Given input: " + input + ", checking diagnostics"); return sn; } @@ -546,7 +547,7 @@ " got: " + main.exception().toString()); } } - List diagnostics = getState().diagnostics(mainKey); + List diagnostics = getState().diagnostics(mainKey).collect(toList()); switch (diagMain) { case DIAG_OK: assertEquals(diagnostics.size(), 0, "Expected no diagnostics, got: " + diagnosticsToString(diagnostics)); @@ -560,7 +561,7 @@ } if (eventChain.mainInfo != null) { for (STEInfo ste : eventChain.updates) { - diagnostics = getState().diagnostics(ste.snippet()); + diagnostics = getState().diagnostics(ste.snippet()).collect(toList()); switch (diagUpdates) { case DIAG_OK: assertEquals(diagnostics.size(), 0, "Expected no diagnostics, got: " + diagnosticsToString(diagnostics)); @@ -637,7 +638,7 @@ SnippetEvent e = events.get(0); Snippet key = e.snippet(); assertEquals(getState().status(key), REJECTED); - List diagnostics = getState().diagnostics(e.snippet()); + List diagnostics = getState().diagnostics(e.snippet()).collect(toList()); assertTrue(diagnostics.size() > 0, "Expected diagnostics, got none"); assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic); assertTrue(key != null, "key must never be null, but it was for: " + input); @@ -656,7 +657,7 @@ List events = assertEval(input, IGNORE_VALUE, null, DiagCheck.DIAG_WARNING, DiagCheck.DIAG_IGNORE, mainInfo, updates); SnippetEvent e = events.get(0); - List diagnostics = getState().diagnostics(e.snippet()); + List diagnostics = getState().diagnostics(e.snippet()).collect(toList()); if (expectedDiagnostic != null) assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic); return e.snippet(); } @@ -704,12 +705,12 @@ String source = declarationKey.source(); assertEquals(declarationKey.name(), expectedName, "Expected " + source + " to have the name: " + expectedName + ", got: " + declarationKey.name()); - List unresolved = getState().unresolvedDependencies(declarationKey); - assertEquals(unresolved.size(), unressz, "Expected " + source + " to have " + unressz - + " unresolved symbols, got: " + unresolved.size()); - List otherCorralledErrors = getState().diagnostics(declarationKey); - assertEquals(otherCorralledErrors.size(), othersz, "Expected " + source + " to have " + othersz - + " other errors, got: " + otherCorralledErrors.size()); + long unresolved = getState().unresolvedDependencies(declarationKey).count(); + assertEquals(unresolved, unressz, "Expected " + source + " to have " + unressz + + " unresolved symbols, got: " + unresolved); + long otherCorralledErrorsCount = getState().diagnostics(declarationKey).count(); + assertEquals(otherCorralledErrorsCount, othersz, "Expected " + source + " to have " + othersz + + " other errors, got: " + otherCorralledErrorsCount); } public void assertKey(Snippet key, Status expectedStatus, SubKind expectedSubKind) { @@ -757,31 +758,20 @@ } public void assertNumberOfActiveVariables(int cnt) { - Collection variables = getState().variables(); - assertEquals(variables.size(), cnt, "Variables : " + variables); + assertEquals(getState().variables().count(), cnt, "Variables : " + getState().variables().collect(toList())); } public void assertNumberOfActiveMethods(int cnt) { - Collection methods = getState().methods(); - assertEquals(methods.size(), cnt, "Methods : " + methods); + assertEquals(getState().methods().count(), cnt, "Methods : " + getState().methods().collect(toList())); } public void assertNumberOfActiveClasses(int cnt) { - Collection classes = getState().types(); - assertEquals(classes.size(), cnt, "Classes : " + classes); - } - - public void assertMembers(Collection members, Set expected) { - assertEquals(members.size(), expected.size(), "Expected : " + expected + ", actual : " + members); - assertEquals(members.stream() - .map(this::getMemberInfo) - .collect(Collectors.toSet()), - expected); + assertEquals(getState().types().count(), cnt, "Types : " + getState().types().collect(toList())); } public void assertKeys(MemberInfo... expected) { int index = 0; - List snippets = getState().snippets(); + List snippets = getState().snippets().collect(toList()); assertEquals(allSnippets.size(), snippets.size()); for (Snippet sn : snippets) { if (sn.kind().isPersistent() && getState().status(sn).isActive()) { @@ -801,7 +791,7 @@ public void assertActiveKeys(Snippet... expected) { int index = 0; - for (Snippet key : getState().snippets()) { + for (Snippet key : getState().snippets().collect(toList())) { if (state.status(key).isActive()) { assertEquals(expected[index], key, String.format("Difference in #%d. Expected: %s, actual: %s", index, key, expected[index])); ++index; @@ -809,31 +799,43 @@ } } - private List filterDeclaredKeys(Predicate p) { - return getActiveKeys().stream() + private void assertActiveSnippets(Stream snippets, Predicate p, String label) { + Set active = getActiveKeys().stream() .filter(p) - .collect(Collectors.toList()); + .collect(Collectors.toSet()); + Set got = snippets + .collect(Collectors.toSet()); + assertEquals(active, got, label); } public void assertVariables() { - assertEquals(getState().variables(), filterDeclaredKeys((key) -> key instanceof VarSnippet), "Variables"); + assertActiveSnippets(getState().variables(), (key) -> key instanceof VarSnippet, "Variables"); } public void assertMethods() { - assertEquals(getState().methods(), filterDeclaredKeys((key) -> key instanceof MethodSnippet), "Methods"); + assertActiveSnippets(getState().methods(), (key) -> key instanceof MethodSnippet, "Methods"); } public void assertClasses() { - assertEquals(getState().types(), filterDeclaredKeys((key) -> key instanceof TypeDeclSnippet), "Classes"); + assertActiveSnippets(getState().types(), (key) -> key instanceof TypeDeclSnippet, "Classes"); + } + + public void assertMembers(Stream members, MemberInfo...expectedInfos) { + Set expected = Stream.of(expectedInfos).collect(Collectors.toSet()); + Set got = members + .map(this::getMemberInfo) + .collect(Collectors.toSet()); + assertEquals(got.size(), expected.size(), "Expected : " + expected + ", actual : " + members); + assertEquals(got, expected); } public void assertVariables(MemberInfo...expected) { - assertMembers(getState().variables(), Stream.of(expected).collect(Collectors.toSet())); + assertMembers(getState().variables(), expected); } public void assertMethods(MemberInfo...expected) { - assertMembers(getState().methods(), Stream.of(expected).collect(Collectors.toSet())); - for (MethodSnippet methodKey : getState().methods()) { + assertMembers(getState().methods(), expected); + getState().methods().forEach(methodKey -> { MemberInfo expectedInfo = null; for (MemberInfo info : expected) { if (info.name.equals(methodKey.name()) && info.type.equals(methodKey.signature())) { @@ -843,11 +845,11 @@ assertNotNull(expectedInfo, "Not found method: " + methodKey.name()); int lastIndexOf = expectedInfo.type.lastIndexOf(')'); assertEquals(methodKey.parameterTypes(), expectedInfo.type.substring(1, lastIndexOf), "Parameter types"); - } + }); } public void assertClasses(MemberInfo...expected) { - assertMembers(getState().types(), Stream.of(expected).collect(Collectors.toSet())); + assertMembers(getState().types(), expected); } public void assertCompletion(String code, String... expected) { diff -r 96a1226aca18 -r 0318f4e75c6d langtools/test/jdk/jshell/RejectedFailedTest.java --- a/langtools/test/jdk/jshell/RejectedFailedTest.java Tue Aug 09 13:22:57 2016 -0700 +++ b/langtools/test/jdk/jshell/RejectedFailedTest.java Tue Aug 09 23:00:49 2016 -0700 @@ -39,6 +39,7 @@ import jdk.jshell.Snippet.Status; import jdk.jshell.SnippetEvent; +import static java.util.stream.Collectors.toList; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -49,7 +50,7 @@ List events = assertEvalFail(input); assertEquals(events.size(), 1, "Expected one event, got: " + events.size()); SnippetEvent e = events.get(0); - List diagnostics = getState().diagnostics(e.snippet()); + List diagnostics = getState().diagnostics(e.snippet()).collect(toList()); assertTrue(diagnostics.size() > 0, "Expected diagnostics, got none"); assertEquals(e.exception(), null, "Expected exception to be null."); assertEquals(e.value(), null, "Expected value to be null."); @@ -60,7 +61,7 @@ SubKind expectedSubKind = kind == Kind.ERRONEOUS ? SubKind.UNKNOWN_SUBKIND : SubKind.METHOD_SUBKIND; assertEquals(key.subKind(), expectedSubKind, "SubKind: "); assertTrue(key.id().compareTo(prevId) > 0, "Current id: " + key.id() + ", previous: " + prevId); - assertEquals(getState().diagnostics(key), diagnostics, "Expected retrieved diagnostics to match, but didn't."); + assertEquals(getState().diagnostics(key).collect(toList()), diagnostics, "Expected retrieved diagnostics to match, but didn't."); assertEquals(key.source(), input, "Expected retrieved source: " + key.source() + " to match input: " + input); assertEquals(getState().status(key), Status.REJECTED, "Expected status of REJECTED, got: " + getState().status(key)); diff -r 96a1226aca18 -r 0318f4e75c6d langtools/test/jdk/jshell/ReplaceTest.java --- a/langtools/test/jdk/jshell/ReplaceTest.java Tue Aug 09 13:22:57 2016 -0700 +++ b/langtools/test/jdk/jshell/ReplaceTest.java Tue Aug 09 23:00:49 2016 -0700 @@ -28,9 +28,9 @@ * @run testng ReplaceTest */ -import java.util.Collection; - +import java.util.Iterator; import java.util.List; +import java.util.stream.Stream; import jdk.jshell.Snippet; import jdk.jshell.MethodSnippet; import jdk.jshell.PersistentSnippet; @@ -42,6 +42,7 @@ import jdk.jshell.SnippetEvent; import jdk.jshell.UnresolvedReferenceException; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; import static jdk.jshell.Snippet.Status.*; import static jdk.jshell.Snippet.SubKind.*; import static org.testng.Assert.assertTrue; @@ -90,17 +91,22 @@ assertActiveKeys(); } + private void identityMatch(Stream got, T expected) { + Iterator it = got.iterator(); + assertTrue(it.hasNext(), "expected exactly one"); + assertTrue(expected == it.next(), "Identity must not change"); + assertFalse(it.hasNext(), "expected exactly one"); + } + public void testReplaceVarToMethod() { Snippet x = varKey(assertEval("int x;")); - Snippet musn = methodKey(assertEval("double mu() { return x * 4; }")); + MethodSnippet musn = methodKey(assertEval("double mu() { return x * 4; }")); assertEval("x == 0;", "true"); assertEval("mu() == 0.0;", "true"); assertEval("double x = 2.5;", ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); - Collection meths = getState().methods(); - assertEquals(meths.size(), 1); - assertTrue(musn == meths.iterator().next(), "Identity must not change"); + identityMatch(getState().methods(), musn); assertEval("x == 2.5;", "true"); assertEval("mu() == 10.0;", "true"); // Auto redefine assertActiveKeys(); @@ -132,15 +138,13 @@ public void testReplaceVarToClass() { Snippet x = varKey(assertEval("int x;")); - Snippet c = classKey(assertEval("class A { double a = 4 * x; }")); + TypeDeclSnippet c = classKey(assertEval("class A { double a = 4 * x; }")); assertEval("x == 0;", "true"); assertEval("new A().a == 0.0;", "true"); assertEval("double x = 2.5;", ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); - Collection classes = getState().types(); - assertEquals(classes.size(), 1); - assertTrue(c == classes.iterator().next(), "Identity must not change"); + identityMatch(getState().types(), c); assertEval("x == 2.5;", "true"); assertEval("new A().a == 10.0;", "true"); assertActiveKeys(); @@ -148,16 +152,14 @@ public void testReplaceMethodToClass() { Snippet x = methodKey(assertEval("int x() { return 0; }")); - Snippet c = classKey(assertEval("class A { double a = 4 * x(); }")); + TypeDeclSnippet c = classKey(assertEval("class A { double a = 4 * x(); }")); assertEval("x() == 0;", "true"); assertEval("new A().a == 0.0;", "true"); assertEval("double x() { return 2.5; }", ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); assertEval("x();", "2.5"); - Collection classes = getState().types(); - assertEquals(classes.size(), 1); - assertTrue(c == classes.iterator().next(), "Identity must not change"); + identityMatch(getState().types(), c); assertEval("x() == 2.5;", "true"); assertEval("new A().a == 10.0;", "true"); assertActiveKeys(); @@ -313,8 +315,8 @@ Snippet assn = ste.snippet(); DeclarationSnippet unsn = ((UnresolvedReferenceException) ste.exception()).getSnippet(); assertEquals(unsn.name(), "A", "Wrong with unresolved"); - assertEquals(getState().unresolvedDependencies(unsn).size(), 1, "Wrong size unresolved"); - assertEquals(getState().diagnostics(unsn).size(), 0, "Expected no diagnostics"); + assertEquals(getState().unresolvedDependencies(unsn).count(), 1, "Wrong size unresolved"); + assertEquals(getState().diagnostics(unsn).count(), 0L, "Expected no diagnostics"); Snippet g = varKey(assertEval("int g = 10;", "10", added(VALID), diff -r 96a1226aca18 -r 0318f4e75c6d langtools/test/jdk/jshell/VariablesTest.java --- a/langtools/test/jdk/jshell/VariablesTest.java Tue Aug 09 13:22:57 2016 -0700 +++ b/langtools/test/jdk/jshell/VariablesTest.java Tue Aug 09 23:00:49 2016 -0700 @@ -39,6 +39,7 @@ import jdk.jshell.SnippetEvent; import org.testng.annotations.Test; +import static java.util.stream.Collectors.toList; import static jdk.jshell.Snippet.Status.*; import static jdk.jshell.Snippet.SubKind.VAR_DECLARATION_SUBKIND; import static org.testng.Assert.assertEquals; @@ -331,7 +332,7 @@ //assertEquals(getState().source(snippet), src); //assertEquals(snippet, undefKey); assertEquals(getState().status(undefKey), RECOVERABLE_NOT_DEFINED); - List unr = getState().unresolvedDependencies((VarSnippet) undefKey); + List unr = getState().unresolvedDependencies((VarSnippet) undefKey).collect(toList());; assertEquals(unr.size(), 1); assertEquals(unr.get(0), "class undefined"); assertVariables(variable("undefined", "d"));