8143964: JShell API: convert query responses to Stream instead of List

Reviewed-by: psandoz, shinyafox
This commit is contained in:
Robert Field 2016-08-09 23:00:49 -07:00
parent 719eeed2d2
commit 81c36d2f40
9 changed files with 283 additions and 149 deletions

View File

@ -973,10 +973,10 @@ public class JShellTool implements MessageHandler {
p.getFileName().toString().endsWith(".jar")); p.getFileName().toString().endsWith(".jar"));
} }
private CompletionProvider snippetCompletion(Supplier<List<? extends Snippet>> snippetsSupplier) { private CompletionProvider snippetCompletion(Supplier<Stream<? extends Snippet>> snippetsSupplier) {
return (prefix, cursor, anchor) -> { return (prefix, cursor, anchor) -> {
anchor[0] = 0; anchor[0] = 0;
return snippetsSupplier.get() .stream() return snippetsSupplier.get()
.flatMap(k -> (k instanceof DeclarationSnippet) .flatMap(k -> (k instanceof DeclarationSnippet)
? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name()) ? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name())
: Stream.of(String.valueOf(k.id()))) : Stream.of(String.valueOf(k.id())))
@ -986,7 +986,7 @@ public class JShellTool implements MessageHandler {
}; };
} }
private CompletionProvider snippetKeywordCompletion(Supplier<List<? extends Snippet>> snippetsSupplier) { private CompletionProvider snippetKeywordCompletion(Supplier<Stream<? extends Snippet>> snippetsSupplier) {
return (code, cursor, anchor) -> { return (code, cursor, anchor) -> {
List<Suggestion> result = new ArrayList<>(); List<Suggestion> result = new ArrayList<>();
result.addAll(KEYWORD_COMPLETION_PROVIDER.completionSuggestions(code, cursor, anchor)); result.addAll(KEYWORD_COMPLETION_PROVIDER.completionSuggestions(code, cursor, anchor));
@ -1020,36 +1020,32 @@ public class JShellTool implements MessageHandler {
// Snippet lists // Snippet lists
List<Snippet> allSnippets() { Stream<Snippet> allSnippets() {
return state.snippets(); return state.snippets();
} }
List<PersistentSnippet> dropableSnippets() { Stream<PersistentSnippet> dropableSnippets() {
return state.snippets().stream() return state.snippets()
.filter(sn -> state.status(sn).isActive() && sn instanceof PersistentSnippet) .filter(sn -> state.status(sn).isActive() && sn instanceof PersistentSnippet)
.map(sn -> (PersistentSnippet) sn) .map(sn -> (PersistentSnippet) sn);
.collect(toList());
} }
List<VarSnippet> allVarSnippets() { Stream<VarSnippet> allVarSnippets() {
return state.snippets().stream() return state.snippets()
.filter(sn -> sn.kind() == Snippet.Kind.VAR) .filter(sn -> sn.kind() == Snippet.Kind.VAR)
.map(sn -> (VarSnippet) sn) .map(sn -> (VarSnippet) sn);
.collect(toList());
} }
List<MethodSnippet> allMethodSnippets() { Stream<MethodSnippet> allMethodSnippets() {
return state.snippets().stream() return state.snippets()
.filter(sn -> sn.kind() == Snippet.Kind.METHOD) .filter(sn -> sn.kind() == Snippet.Kind.METHOD)
.map(sn -> (MethodSnippet) sn) .map(sn -> (MethodSnippet) sn);
.collect(toList());
} }
List<TypeDeclSnippet> allTypeSnippets() { Stream<TypeDeclSnippet> allTypeSnippets() {
return state.snippets().stream() return state.snippets()
.filter(sn -> sn.kind() == Snippet.Kind.TYPE_DECL) .filter(sn -> sn.kind() == Snippet.Kind.TYPE_DECL)
.map(sn -> (TypeDeclSnippet) sn) .map(sn -> (TypeDeclSnippet) sn);
.collect(toList());
} }
// Table of commands -- with command forms, argument kinds, helpKey message, implementation, ... // Table of commands -- with command forms, argument kinds, helpKey message, implementation, ...
@ -1549,7 +1545,7 @@ public class JShellTool implements MessageHandler {
* string * string
* @return a Stream of referenced snippets or null if no matches are found * @return a Stream of referenced snippets or null if no matches are found
*/ */
private <T extends Snippet> Stream<T> argsOptionsToSnippets(List<T> snippets, private <T extends Snippet> Stream<T> argsOptionsToSnippets(Supplier<Stream<T>> snippetSupplier,
Predicate<Snippet> defFilter, String rawargs, String cmd) { Predicate<Snippet> defFilter, String rawargs, String cmd) {
ArgTokenizer at = new ArgTokenizer(cmd, rawargs.trim()); ArgTokenizer at = new ArgTokenizer(cmd, rawargs.trim());
at.allowedOptions("-all", "-start"); at.allowedOptions("-all", "-start");
@ -1571,38 +1567,38 @@ public class JShellTool implements MessageHandler {
} }
if (at.hasOption("-all")) { if (at.hasOption("-all")) {
// all snippets including start-up, failed, and overwritten // all snippets including start-up, failed, and overwritten
return snippets.stream(); return snippetSupplier.get();
} }
if (at.hasOption("-start")) { if (at.hasOption("-start")) {
// start-up snippets // start-up snippets
return snippets.stream() return snippetSupplier.get()
.filter(this::inStartUp); .filter(this::inStartUp);
} }
if (args.isEmpty()) { if (args.isEmpty()) {
// Default is all active user snippets // Default is all active user snippets
return snippets.stream() return snippetSupplier.get()
.filter(defFilter); .filter(defFilter);
} }
return argsToSnippets(snippets, args); return argsToSnippets(snippetSupplier, args);
} }
/** /**
* Convert user arguments to a Stream of snippets referenced by those * Convert user arguments to a Stream of snippets referenced by those
* arguments. * 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 * @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 * @return a Stream of referenced snippets or null if no matches to specific
* arg * arg
*/ */
private <T extends Snippet> Stream<T> argsToSnippets(List<T> snippets, private <T extends Snippet> Stream<T> argsToSnippets(Supplier<Stream<T>> snippetSupplier,
List<String> args) { List<String> args) {
Stream<T> result = null; Stream<T> result = null;
for (String arg : args) { for (String arg : args) {
// Find the best match // Find the best match
Stream<T> st = layeredSnippetSearch(snippets, arg); Stream<T> st = layeredSnippetSearch(snippetSupplier, arg);
if (st == null) { if (st == null) {
Stream<Snippet> est = layeredSnippetSearch(state.snippets(), arg); Stream<Snippet> est = layeredSnippetSearch(state::snippets, arg);
if (est == null) { if (est == null) {
errormsg("jshell.err.no.such.snippets", arg); errormsg("jshell.err.no.such.snippets", arg);
} else { } else {
@ -1620,10 +1616,10 @@ public class JShellTool implements MessageHandler {
return result; return result;
} }
private <T extends Snippet> Stream<T> layeredSnippetSearch(List<T> snippets, String arg) { private <T extends Snippet> Stream<T> layeredSnippetSearch(Supplier<Stream<T>> snippetSupplier, String arg) {
return nonEmptyStream( return nonEmptyStream(
// the stream supplier // the stream supplier
() -> snippets.stream(), snippetSupplier,
// look for active user declarations matching the name // look for active user declarations matching the name
sn -> isActive(sn) && matchingDeclaration(sn, arg), sn -> isActive(sn) && matchingDeclaration(sn, arg),
// else, look for any declarations matching the name // else, look for any declarations matching the name
@ -1648,7 +1644,7 @@ public class JShellTool implements MessageHandler {
errormsg("jshell.err.drop.arg"); errormsg("jshell.err.drop.arg");
return false; return false;
} }
Stream<PersistentSnippet> stream = argsToSnippets(dropableSnippets(), args); Stream<PersistentSnippet> stream = argsToSnippets(this::dropableSnippets, args);
if (stream == null) { if (stream == null) {
// Snippet not found. Error already printed // Snippet not found. Error already printed
fluffmsg("jshell.msg.see.classes.etc"); fluffmsg("jshell.msg.see.classes.etc");
@ -1670,7 +1666,7 @@ public class JShellTool implements MessageHandler {
} }
private boolean cmdEdit(String arg) { private boolean cmdEdit(String arg) {
Stream<Snippet> stream = argsOptionsToSnippets(state.snippets(), Stream<Snippet> stream = argsOptionsToSnippets(state::snippets,
this::mainActive, arg, "/edit"); this::mainActive, arg, "/edit");
if (stream == null) { if (stream == null) {
return false; return false;
@ -1775,7 +1771,7 @@ public class JShellTool implements MessageHandler {
if (arg.length() >= 2 && "-history".startsWith(arg)) { if (arg.length() >= 2 && "-history".startsWith(arg)) {
return cmdHistory(); return cmdHistory();
} }
Stream<Snippet> stream = argsOptionsToSnippets(state.snippets(), Stream<Snippet> stream = argsOptionsToSnippets(state::snippets,
this::mainActive, arg, "/list"); this::mainActive, arg, "/list");
if (stream == null) { if (stream == null) {
return false; return false;
@ -1896,13 +1892,12 @@ public class JShellTool implements MessageHandler {
} else if (at.hasOption("-start")) { } else if (at.hasOption("-start")) {
writer.append(startup); writer.append(startup);
} else { } else {
List<Snippet> sns = at.hasOption("-all") String sources = (at.hasOption("-all")
? state.snippets() ? state.snippets()
: state.snippets().stream().filter(this::mainActive).collect(toList()); : state.snippets().filter(this::mainActive))
for (Snippet sn : sns) { .map(Snippet::source)
writer.write(sn.source()); .collect(Collectors.joining("\n"));
writer.write("\n"); writer.write(sources);
}
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
errormsg("jshell.err.file.not.found", "/save", filename, e.getMessage()); errormsg("jshell.err.file.not.found", "/save", filename, e.getMessage());
@ -1915,7 +1910,7 @@ public class JShellTool implements MessageHandler {
} }
private boolean cmdVars(String arg) { private boolean cmdVars(String arg) {
Stream<VarSnippet> stream = argsOptionsToSnippets(allVarSnippets(), Stream<VarSnippet> stream = argsOptionsToSnippets(this::allVarSnippets,
this::isActive, arg, "/vars"); this::isActive, arg, "/vars");
if (stream == null) { if (stream == null) {
return false; return false;
@ -1931,7 +1926,7 @@ public class JShellTool implements MessageHandler {
} }
private boolean cmdMethods(String arg) { private boolean cmdMethods(String arg) {
Stream<MethodSnippet> stream = argsOptionsToSnippets(allMethodSnippets(), Stream<MethodSnippet> stream = argsOptionsToSnippets(this::allMethodSnippets,
this::isActive, arg, "/methods"); this::isActive, arg, "/methods");
if (stream == null) { if (stream == null) {
return false; return false;
@ -1943,7 +1938,7 @@ public class JShellTool implements MessageHandler {
} }
private boolean cmdTypes(String arg) { private boolean cmdTypes(String arg) {
Stream<TypeDeclSnippet> stream = argsOptionsToSnippets(allTypeSnippets(), Stream<TypeDeclSnippet> stream = argsOptionsToSnippets(this::allTypeSnippets,
this::isActive, arg, "/types"); this::isActive, arg, "/types");
if (stream == null) { if (stream == null) {
return false; return false;
@ -1982,7 +1977,7 @@ public class JShellTool implements MessageHandler {
} }
private boolean cmdUseHistoryEntry(int index) { private boolean cmdUseHistoryEntry(int index) {
List<Snippet> keys = state.snippets(); List<Snippet> keys = state.snippets().collect(toList());
if (index < 0) if (index < 0)
index += keys.size(); index += keys.size();
else else
@ -2012,7 +2007,7 @@ public class JShellTool implements MessageHandler {
} }
private boolean rerunHistoryEntryById(String id) { private boolean rerunHistoryEntryById(String id) {
Optional<Snippet> snippet = state.snippets().stream() Optional<Snippet> snippet = state.snippets()
.filter(s -> s.id().equals(id)) .filter(s -> s.id().equals(id))
.findFirst(); .findFirst();
return snippet.map(s -> { return snippet.map(s -> {
@ -2135,7 +2130,7 @@ public class JShellTool implements MessageHandler {
debug("Event with null key: %s", ste); debug("Event with null key: %s", ste);
return false; return false;
} }
List<Diag> diagnostics = state.diagnostics(sn); List<Diag> diagnostics = state.diagnostics(sn).collect(toList());
String source = sn.source(); String source = sn.source();
if (ste.causeSnippet() == null) { if (ste.causeSnippet() == null) {
// main event // main event
@ -2212,7 +2207,7 @@ public class JShellTool implements MessageHandler {
//where //where
void printUnresolvedException(UnresolvedReferenceException ex) { void printUnresolvedException(UnresolvedReferenceException ex) {
DeclarationSnippet corralled = ex.getSnippet(); DeclarationSnippet corralled = ex.getSnippet();
List<Diag> otherErrors = errorsOnly(state.diagnostics(corralled)); List<Diag> otherErrors = errorsOnly(state.diagnostics(corralled).collect(toList()));
new DisplayEvent(corralled, state.status(corralled), FormatAction.USED, true, null, otherErrors) new DisplayEvent(corralled, state.status(corralled), FormatAction.USED, true, null, otherErrors)
.displayDeclarationAndValue(); .displayDeclarationAndValue();
} }
@ -2280,13 +2275,13 @@ public class JShellTool implements MessageHandler {
for (Diag d : errors) { for (Diag d : errors) {
displayDiagnostics(sn.source(), d, errorLines); displayDiagnostics(sn.source(), d, errorLines);
} }
int unresolvedCount; long unresolvedCount;
if (sn instanceof DeclarationSnippet && (status == Status.RECOVERABLE_DEFINED || status == Status.RECOVERABLE_NOT_DEFINED)) { if (sn instanceof DeclarationSnippet && (status == Status.RECOVERABLE_DEFINED || status == Status.RECOVERABLE_NOT_DEFINED)) {
resolution = (status == Status.RECOVERABLE_NOT_DEFINED) resolution = (status == Status.RECOVERABLE_NOT_DEFINED)
? FormatResolve.NOTDEFINED ? FormatResolve.NOTDEFINED
: FormatResolve.DEFINED; : FormatResolve.DEFINED;
unresolved = unresolved((DeclarationSnippet) sn); unresolved = unresolved((DeclarationSnippet) sn);
unresolvedCount = state.unresolvedDependencies((DeclarationSnippet) sn).size(); unresolvedCount = state.unresolvedDependencies((DeclarationSnippet) sn).count();
} else { } else {
resolution = FormatResolve.OK; resolution = FormatResolve.OK;
unresolved = ""; unresolved = "";
@ -2305,7 +2300,7 @@ public class JShellTool implements MessageHandler {
} }
private String unresolved(DeclarationSnippet key) { private String unresolved(DeclarationSnippet key) {
List<String> unr = state.unresolvedDependencies(key); List<String> unr = state.unresolvedDependencies(key).collect(toList());
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
int fromLast = unr.size(); int fromLast = unr.size();
if (fromLast > 0) { if (fromLast > 0) {

View File

@ -43,6 +43,7 @@ import java.util.function.BiFunction;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Stream;
import jdk.internal.jshell.debug.InternalDebugControl; import jdk.internal.jshell.debug.InternalDebugControl;
import jdk.jshell.Snippet.Status; import jdk.jshell.Snippet.Status;
import jdk.jshell.execution.JDIDefaultExecutionControl; import jdk.jshell.execution.JDIDefaultExecutionControl;
@ -504,9 +505,9 @@ public class JShell implements AutoCloseable {
* @return the snippets for all current snippets in id order. * @return the snippets for all current snippets in id order.
* @throws IllegalStateException if this JShell instance is closed. * @throws IllegalStateException if this JShell instance is closed.
*/ */
public List<Snippet> snippets() throws IllegalStateException { public Stream<Snippet> snippets() throws IllegalStateException {
checkIfAlive(); checkIfAlive();
return Collections.unmodifiableList(maps.snippetList()); return maps.snippetList().stream();
} }
/** /**
@ -518,11 +519,10 @@ public class JShell implements AutoCloseable {
* @return the active declared variables. * @return the active declared variables.
* @throws IllegalStateException if this JShell instance is closed. * @throws IllegalStateException if this JShell instance is closed.
*/ */
public List<VarSnippet> variables() throws IllegalStateException { public Stream<VarSnippet> variables() throws IllegalStateException {
return snippets().stream() return snippets()
.filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.VAR) .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.VAR)
.map(sn -> (VarSnippet) sn) .map(sn -> (VarSnippet) sn);
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
} }
/** /**
@ -534,11 +534,10 @@ public class JShell implements AutoCloseable {
* @return the active declared methods. * @return the active declared methods.
* @throws IllegalStateException if this JShell instance is closed. * @throws IllegalStateException if this JShell instance is closed.
*/ */
public List<MethodSnippet> methods() throws IllegalStateException { public Stream<MethodSnippet> methods() throws IllegalStateException {
return snippets().stream() return snippets()
.filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.METHOD) .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.METHOD)
.map(sn -> (MethodSnippet)sn) .map(sn -> (MethodSnippet)sn);
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
} }
/** /**
@ -550,11 +549,10 @@ public class JShell implements AutoCloseable {
* @return the active declared type declarations. * @return the active declared type declarations.
* @throws IllegalStateException if this JShell instance is closed. * @throws IllegalStateException if this JShell instance is closed.
*/ */
public List<TypeDeclSnippet> types() throws IllegalStateException { public Stream<TypeDeclSnippet> types() throws IllegalStateException {
return snippets().stream() return snippets()
.filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.TYPE_DECL) .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.TYPE_DECL)
.map(sn -> (TypeDeclSnippet) sn) .map(sn -> (TypeDeclSnippet) sn);
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
} }
/** /**
@ -566,11 +564,10 @@ public class JShell implements AutoCloseable {
* @return the active declared import declarations. * @return the active declared import declarations.
* @throws IllegalStateException if this JShell instance is closed. * @throws IllegalStateException if this JShell instance is closed.
*/ */
public List<ImportSnippet> imports() throws IllegalStateException { public Stream<ImportSnippet> imports() throws IllegalStateException {
return snippets().stream() return snippets()
.filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.IMPORT) .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.IMPORT)
.map(sn -> (ImportSnippet) sn) .map(sn -> (ImportSnippet) sn);
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
} }
/** /**
@ -598,8 +595,8 @@ public class JShell implements AutoCloseable {
* @throws IllegalArgumentException if the snippet is not associated with * @throws IllegalArgumentException if the snippet is not associated with
* this {@code JShell} instance. * this {@code JShell} instance.
*/ */
public List<Diag> diagnostics(Snippet snippet) { public Stream<Diag> diagnostics(Snippet snippet) {
return Collections.unmodifiableList(checkValidSnippet(snippet).diagnostics()); return checkValidSnippet(snippet).diagnostics().stream();
} }
/** /**
@ -611,13 +608,13 @@ public class JShell implements AutoCloseable {
* {@code eval()} or {@code drop()} of another snippet causes * {@code eval()} or {@code drop()} of another snippet causes
* an update of a dependency. * an update of a dependency.
* @param snippet the declaration {@code Snippet} to look up * @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 IllegalStateException if this {@code JShell} instance is closed.
* @throws IllegalArgumentException if the snippet is not associated with * @throws IllegalArgumentException if the snippet is not associated with
* this {@code JShell} instance. * this {@code JShell} instance.
*/ */
public List<String> unresolvedDependencies(DeclarationSnippet snippet) { public Stream<String> unresolvedDependencies(DeclarationSnippet snippet) {
return Collections.unmodifiableList(checkValidSnippet(snippet).unresolved()); return checkValidSnippet(snippet).unresolved().stream();
} }
/** /**

View File

@ -414,25 +414,29 @@ final class Unit {
// types are the same. if so, consider it an overwrite replacement. // types are the same. if so, consider it an overwrite replacement.
private Status overwriteMatchingMethod(MethodSnippet msi) { private Status overwriteMatchingMethod(MethodSnippet msi) {
String qpt = msi.qualifiedParameterTypes(); String qpt = msi.qualifiedParameterTypes();
List<MethodSnippet> 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 // Look through all methods for a method of the same name, with the
// same computed qualified parameter types // same computed qualified parameter types
Status overwrittenStatus = null; Status overwrittenStatus = null;
for (MethodSnippet sn : state.methods()) { for (MethodSnippet sn : matching) {
if (sn != null && sn != msi && sn.status().isActive() && sn.name().equals(msi.name())) { overwrittenStatus = sn.status();
if (qpt.equals(sn.qualifiedParameterTypes())) { SnippetEvent se = new SnippetEvent(
overwrittenStatus = sn.status(); sn, overwrittenStatus, OVERWRITTEN,
SnippetEvent se = new SnippetEvent( false, msi, null, null);
sn, overwrittenStatus, OVERWRITTEN, sn.setOverwritten();
false, msi, null, null); secondaryEvents.add(se);
sn.setOverwritten(); state.debug(DBG_EVNT,
secondaryEvents.add(se); "Overwrite event #%d -- key: %s before: %s status: %s sig: %b cause: %s\n",
state.debug(DBG_EVNT, secondaryEvents.size(), se.snippet(), se.previousStatus(),
"Overwrite event #%d -- key: %s before: %s status: %s sig: %b cause: %s\n", se.status(), se.isSignatureChange(), se.causeSnippet());
secondaryEvents.size(), se.snippet(), se.previousStatus(),
se.status(), se.isSignatureChange(), se.causeSnippet());
}
}
} }
return overwrittenStatus; return overwrittenStatus;
} }

View File

@ -41,6 +41,7 @@ import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import jdk.jshell.Diag; import jdk.jshell.Diag;
import static java.util.stream.Collectors.toList;
import static jdk.jshell.Snippet.Status.VALID; import static jdk.jshell.Snippet.Status.VALID;
import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED; import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED;
import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED; import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED;
@ -210,8 +211,8 @@ public class ClassesTest extends KullaTesting {
ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET)); 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 // It is random which one it shows up in, but cyclic error should be there
List<Diag> diagsA = getState().diagnostics(a); List<Diag> diagsA = getState().diagnostics(a).collect(toList());
List<Diag> diagsB = getState().diagnostics(b); List<Diag> diagsB = getState().diagnostics(b).collect(toList());
List<Diag> diags; List<Diag> diags;
if (diagsA.isEmpty()) { if (diagsA.isEmpty()) {
diags = diagsB; diags = diagsB;

View File

@ -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 <T> void checkStreamMatch(Stream<T> result, T... expected) {
Set<T> sns = result.collect(toSet());
Set<T> 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()");
}
}

View File

@ -70,6 +70,7 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
import jdk.jshell.Diag; import jdk.jshell.Diag;
import static java.util.stream.Collectors.toList;
import static jdk.jshell.Snippet.Status.*; import static jdk.jshell.Snippet.Status.*;
import static org.testng.Assert.*; import static org.testng.Assert.*;
import static jdk.jshell.Snippet.SubKind.METHOD_SUBKIND; import static jdk.jshell.Snippet.SubKind.METHOD_SUBKIND;
@ -183,7 +184,7 @@ public class KullaTesting {
} }
public List<String> assertUnresolvedDependencies(DeclarationSnippet key, int unresolvedSize) { public List<String> assertUnresolvedDependencies(DeclarationSnippet key, int unresolvedSize) {
List<String> unresolved = getState().unresolvedDependencies(key); List<String> unresolved = getState().unresolvedDependencies(key).collect(toList());
assertEquals(unresolved.size(), unresolvedSize, "Input: " + key.source() + ", checking unresolved: "); assertEquals(unresolved.size(), unresolvedSize, "Input: " + key.source() + ", checking unresolved: ");
return unresolved; return unresolved;
} }
@ -202,8 +203,8 @@ public class KullaTesting {
SnippetEvent ste = events.get(0); SnippetEvent ste = events.get(0);
DeclarationSnippet sn = ((UnresolvedReferenceException) ste.exception()).getSnippet(); DeclarationSnippet sn = ((UnresolvedReferenceException) ste.exception()).getSnippet();
assertEquals(sn.name(), name, "Given input: " + input + ", checking name"); assertEquals(sn.name(), name, "Given input: " + input + ", checking name");
assertEquals(getState().unresolvedDependencies(sn).size(), unresolvedSize, "Given input: " + input + ", checking unresolved"); assertEquals(getState().unresolvedDependencies(sn).count(), unresolvedSize, "Given input: " + input + ", checking unresolved");
assertEquals(getState().diagnostics(sn).size(), diagnosticsSize, "Given input: " + input + ", checking diagnostics"); assertEquals(getState().diagnostics(sn).count(), (long) diagnosticsSize, "Given input: " + input + ", checking diagnostics");
return sn; return sn;
} }
@ -546,7 +547,7 @@ public class KullaTesting {
" got: " + main.exception().toString()); " got: " + main.exception().toString());
} }
} }
List<Diag> diagnostics = getState().diagnostics(mainKey); List<Diag> diagnostics = getState().diagnostics(mainKey).collect(toList());
switch (diagMain) { switch (diagMain) {
case DIAG_OK: case DIAG_OK:
assertEquals(diagnostics.size(), 0, "Expected no diagnostics, got: " + diagnosticsToString(diagnostics)); assertEquals(diagnostics.size(), 0, "Expected no diagnostics, got: " + diagnosticsToString(diagnostics));
@ -560,7 +561,7 @@ public class KullaTesting {
} }
if (eventChain.mainInfo != null) { if (eventChain.mainInfo != null) {
for (STEInfo ste : eventChain.updates) { for (STEInfo ste : eventChain.updates) {
diagnostics = getState().diagnostics(ste.snippet()); diagnostics = getState().diagnostics(ste.snippet()).collect(toList());
switch (diagUpdates) { switch (diagUpdates) {
case DIAG_OK: case DIAG_OK:
assertEquals(diagnostics.size(), 0, "Expected no diagnostics, got: " + diagnosticsToString(diagnostics)); assertEquals(diagnostics.size(), 0, "Expected no diagnostics, got: " + diagnosticsToString(diagnostics));
@ -637,7 +638,7 @@ public class KullaTesting {
SnippetEvent e = events.get(0); SnippetEvent e = events.get(0);
Snippet key = e.snippet(); Snippet key = e.snippet();
assertEquals(getState().status(key), REJECTED); assertEquals(getState().status(key), REJECTED);
List<Diag> diagnostics = getState().diagnostics(e.snippet()); List<Diag> diagnostics = getState().diagnostics(e.snippet()).collect(toList());
assertTrue(diagnostics.size() > 0, "Expected diagnostics, got none"); assertTrue(diagnostics.size() > 0, "Expected diagnostics, got none");
assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic); assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic);
assertTrue(key != null, "key must never be null, but it was for: " + input); assertTrue(key != null, "key must never be null, but it was for: " + input);
@ -656,7 +657,7 @@ public class KullaTesting {
List<SnippetEvent> events = assertEval(input, IGNORE_VALUE, null, List<SnippetEvent> events = assertEval(input, IGNORE_VALUE, null,
DiagCheck.DIAG_WARNING, DiagCheck.DIAG_IGNORE, mainInfo, updates); DiagCheck.DIAG_WARNING, DiagCheck.DIAG_IGNORE, mainInfo, updates);
SnippetEvent e = events.get(0); SnippetEvent e = events.get(0);
List<Diag> diagnostics = getState().diagnostics(e.snippet()); List<Diag> diagnostics = getState().diagnostics(e.snippet()).collect(toList());
if (expectedDiagnostic != null) assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic); if (expectedDiagnostic != null) assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic);
return e.snippet(); return e.snippet();
} }
@ -704,12 +705,12 @@ public class KullaTesting {
String source = declarationKey.source(); String source = declarationKey.source();
assertEquals(declarationKey.name(), expectedName, assertEquals(declarationKey.name(), expectedName,
"Expected " + source + " to have the name: " + expectedName + ", got: " + declarationKey.name()); "Expected " + source + " to have the name: " + expectedName + ", got: " + declarationKey.name());
List<String> unresolved = getState().unresolvedDependencies(declarationKey); long unresolved = getState().unresolvedDependencies(declarationKey).count();
assertEquals(unresolved.size(), unressz, "Expected " + source + " to have " + unressz assertEquals(unresolved, unressz, "Expected " + source + " to have " + unressz
+ " unresolved symbols, got: " + unresolved.size()); + " unresolved symbols, got: " + unresolved);
List<Diag> otherCorralledErrors = getState().diagnostics(declarationKey); long otherCorralledErrorsCount = getState().diagnostics(declarationKey).count();
assertEquals(otherCorralledErrors.size(), othersz, "Expected " + source + " to have " + othersz assertEquals(otherCorralledErrorsCount, othersz, "Expected " + source + " to have " + othersz
+ " other errors, got: " + otherCorralledErrors.size()); + " other errors, got: " + otherCorralledErrorsCount);
} }
public void assertKey(Snippet key, Status expectedStatus, SubKind expectedSubKind) { public void assertKey(Snippet key, Status expectedStatus, SubKind expectedSubKind) {
@ -757,31 +758,20 @@ public class KullaTesting {
} }
public void assertNumberOfActiveVariables(int cnt) { public void assertNumberOfActiveVariables(int cnt) {
Collection<VarSnippet> variables = getState().variables(); assertEquals(getState().variables().count(), cnt, "Variables : " + getState().variables().collect(toList()));
assertEquals(variables.size(), cnt, "Variables : " + variables);
} }
public void assertNumberOfActiveMethods(int cnt) { public void assertNumberOfActiveMethods(int cnt) {
Collection<MethodSnippet> methods = getState().methods(); assertEquals(getState().methods().count(), cnt, "Methods : " + getState().methods().collect(toList()));
assertEquals(methods.size(), cnt, "Methods : " + methods);
} }
public void assertNumberOfActiveClasses(int cnt) { public void assertNumberOfActiveClasses(int cnt) {
Collection<TypeDeclSnippet> classes = getState().types(); assertEquals(getState().types().count(), cnt, "Types : " + getState().types().collect(toList()));
assertEquals(classes.size(), cnt, "Classes : " + classes);
}
public void assertMembers(Collection<? extends Snippet> members, Set<MemberInfo> expected) {
assertEquals(members.size(), expected.size(), "Expected : " + expected + ", actual : " + members);
assertEquals(members.stream()
.map(this::getMemberInfo)
.collect(Collectors.toSet()),
expected);
} }
public void assertKeys(MemberInfo... expected) { public void assertKeys(MemberInfo... expected) {
int index = 0; int index = 0;
List<Snippet> snippets = getState().snippets(); List<Snippet> snippets = getState().snippets().collect(toList());
assertEquals(allSnippets.size(), snippets.size()); assertEquals(allSnippets.size(), snippets.size());
for (Snippet sn : snippets) { for (Snippet sn : snippets) {
if (sn.kind().isPersistent() && getState().status(sn).isActive()) { if (sn.kind().isPersistent() && getState().status(sn).isActive()) {
@ -801,7 +791,7 @@ public class KullaTesting {
public void assertActiveKeys(Snippet... expected) { public void assertActiveKeys(Snippet... expected) {
int index = 0; int index = 0;
for (Snippet key : getState().snippets()) { for (Snippet key : getState().snippets().collect(toList())) {
if (state.status(key).isActive()) { if (state.status(key).isActive()) {
assertEquals(expected[index], key, String.format("Difference in #%d. Expected: %s, actual: %s", index, key, expected[index])); assertEquals(expected[index], key, String.format("Difference in #%d. Expected: %s, actual: %s", index, key, expected[index]));
++index; ++index;
@ -809,31 +799,43 @@ public class KullaTesting {
} }
} }
private List<Snippet> filterDeclaredKeys(Predicate<Snippet> p) { private void assertActiveSnippets(Stream<? extends Snippet> snippets, Predicate<Snippet> p, String label) {
return getActiveKeys().stream() Set<Snippet> active = getActiveKeys().stream()
.filter(p) .filter(p)
.collect(Collectors.toList()); .collect(Collectors.toSet());
Set<Snippet> got = snippets
.collect(Collectors.toSet());
assertEquals(active, got, label);
} }
public void assertVariables() { public void assertVariables() {
assertEquals(getState().variables(), filterDeclaredKeys((key) -> key instanceof VarSnippet), "Variables"); assertActiveSnippets(getState().variables(), (key) -> key instanceof VarSnippet, "Variables");
} }
public void assertMethods() { public void assertMethods() {
assertEquals(getState().methods(), filterDeclaredKeys((key) -> key instanceof MethodSnippet), "Methods"); assertActiveSnippets(getState().methods(), (key) -> key instanceof MethodSnippet, "Methods");
} }
public void assertClasses() { public void assertClasses() {
assertEquals(getState().types(), filterDeclaredKeys((key) -> key instanceof TypeDeclSnippet), "Classes"); assertActiveSnippets(getState().types(), (key) -> key instanceof TypeDeclSnippet, "Classes");
}
public void assertMembers(Stream<? extends Snippet> members, MemberInfo...expectedInfos) {
Set<MemberInfo> expected = Stream.of(expectedInfos).collect(Collectors.toSet());
Set<MemberInfo> 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) { public void assertVariables(MemberInfo...expected) {
assertMembers(getState().variables(), Stream.of(expected).collect(Collectors.toSet())); assertMembers(getState().variables(), expected);
} }
public void assertMethods(MemberInfo...expected) { public void assertMethods(MemberInfo...expected) {
assertMembers(getState().methods(), Stream.of(expected).collect(Collectors.toSet())); assertMembers(getState().methods(), expected);
for (MethodSnippet methodKey : getState().methods()) { getState().methods().forEach(methodKey -> {
MemberInfo expectedInfo = null; MemberInfo expectedInfo = null;
for (MemberInfo info : expected) { for (MemberInfo info : expected) {
if (info.name.equals(methodKey.name()) && info.type.equals(methodKey.signature())) { if (info.name.equals(methodKey.name()) && info.type.equals(methodKey.signature())) {
@ -843,11 +845,11 @@ public class KullaTesting {
assertNotNull(expectedInfo, "Not found method: " + methodKey.name()); assertNotNull(expectedInfo, "Not found method: " + methodKey.name());
int lastIndexOf = expectedInfo.type.lastIndexOf(')'); int lastIndexOf = expectedInfo.type.lastIndexOf(')');
assertEquals(methodKey.parameterTypes(), expectedInfo.type.substring(1, lastIndexOf), "Parameter types"); assertEquals(methodKey.parameterTypes(), expectedInfo.type.substring(1, lastIndexOf), "Parameter types");
} });
} }
public void assertClasses(MemberInfo...expected) { 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) { public void assertCompletion(String code, String... expected) {

View File

@ -39,6 +39,7 @@ import jdk.jshell.Snippet.Kind;
import jdk.jshell.Snippet.Status; import jdk.jshell.Snippet.Status;
import jdk.jshell.SnippetEvent; import jdk.jshell.SnippetEvent;
import static java.util.stream.Collectors.toList;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
@ -49,7 +50,7 @@ public class RejectedFailedTest extends KullaTesting {
List<SnippetEvent> events = assertEvalFail(input); List<SnippetEvent> events = assertEvalFail(input);
assertEquals(events.size(), 1, "Expected one event, got: " + events.size()); assertEquals(events.size(), 1, "Expected one event, got: " + events.size());
SnippetEvent e = events.get(0); SnippetEvent e = events.get(0);
List<Diag> diagnostics = getState().diagnostics(e.snippet()); List<Diag> diagnostics = getState().diagnostics(e.snippet()).collect(toList());
assertTrue(diagnostics.size() > 0, "Expected diagnostics, got none"); assertTrue(diagnostics.size() > 0, "Expected diagnostics, got none");
assertEquals(e.exception(), null, "Expected exception to be null."); assertEquals(e.exception(), null, "Expected exception to be null.");
assertEquals(e.value(), null, "Expected value to be null."); assertEquals(e.value(), null, "Expected value to be null.");
@ -60,7 +61,7 @@ public class RejectedFailedTest extends KullaTesting {
SubKind expectedSubKind = kind == Kind.ERRONEOUS ? SubKind.UNKNOWN_SUBKIND : SubKind.METHOD_SUBKIND; SubKind expectedSubKind = kind == Kind.ERRONEOUS ? SubKind.UNKNOWN_SUBKIND : SubKind.METHOD_SUBKIND;
assertEquals(key.subKind(), expectedSubKind, "SubKind: "); assertEquals(key.subKind(), expectedSubKind, "SubKind: ");
assertTrue(key.id().compareTo(prevId) > 0, "Current id: " + key.id() + ", previous: " + prevId); 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: " + assertEquals(key.source(), input, "Expected retrieved source: " +
key.source() + " to match input: " + input); key.source() + " to match input: " + input);
assertEquals(getState().status(key), Status.REJECTED, "Expected status of REJECTED, got: " + getState().status(key)); assertEquals(getState().status(key), Status.REJECTED, "Expected status of REJECTED, got: " + getState().status(key));

View File

@ -28,9 +28,9 @@
* @run testng ReplaceTest * @run testng ReplaceTest
*/ */
import java.util.Collection; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.stream.Stream;
import jdk.jshell.Snippet; import jdk.jshell.Snippet;
import jdk.jshell.MethodSnippet; import jdk.jshell.MethodSnippet;
import jdk.jshell.PersistentSnippet; import jdk.jshell.PersistentSnippet;
@ -42,6 +42,7 @@ import org.testng.annotations.Test;
import jdk.jshell.SnippetEvent; import jdk.jshell.SnippetEvent;
import jdk.jshell.UnresolvedReferenceException; import jdk.jshell.UnresolvedReferenceException;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static jdk.jshell.Snippet.Status.*; import static jdk.jshell.Snippet.Status.*;
import static jdk.jshell.Snippet.SubKind.*; import static jdk.jshell.Snippet.SubKind.*;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
@ -90,17 +91,22 @@ public class ReplaceTest extends KullaTesting {
assertActiveKeys(); assertActiveKeys();
} }
private <T extends Snippet> void identityMatch(Stream<T> got, T expected) {
Iterator<T> 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() { public void testReplaceVarToMethod() {
Snippet x = varKey(assertEval("int x;")); 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("x == 0;", "true");
assertEval("mu() == 0.0;", "true"); assertEval("mu() == 0.0;", "true");
assertEval("double x = 2.5;", assertEval("double x = 2.5;",
ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
Collection<MethodSnippet> meths = getState().methods(); identityMatch(getState().methods(), musn);
assertEquals(meths.size(), 1);
assertTrue(musn == meths.iterator().next(), "Identity must not change");
assertEval("x == 2.5;", "true"); assertEval("x == 2.5;", "true");
assertEval("mu() == 10.0;", "true"); // Auto redefine assertEval("mu() == 10.0;", "true"); // Auto redefine
assertActiveKeys(); assertActiveKeys();
@ -132,15 +138,13 @@ public class ReplaceTest extends KullaTesting {
public void testReplaceVarToClass() { public void testReplaceVarToClass() {
Snippet x = varKey(assertEval("int x;")); 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("x == 0;", "true");
assertEval("new A().a == 0.0;", "true"); assertEval("new A().a == 0.0;", "true");
assertEval("double x = 2.5;", assertEval("double x = 2.5;",
ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
Collection<TypeDeclSnippet> classes = getState().types(); identityMatch(getState().types(), c);
assertEquals(classes.size(), 1);
assertTrue(c == classes.iterator().next(), "Identity must not change");
assertEval("x == 2.5;", "true"); assertEval("x == 2.5;", "true");
assertEval("new A().a == 10.0;", "true"); assertEval("new A().a == 10.0;", "true");
assertActiveKeys(); assertActiveKeys();
@ -148,16 +152,14 @@ public class ReplaceTest extends KullaTesting {
public void testReplaceMethodToClass() { public void testReplaceMethodToClass() {
Snippet x = methodKey(assertEval("int x() { return 0; }")); 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("x() == 0;", "true");
assertEval("new A().a == 0.0;", "true"); assertEval("new A().a == 0.0;", "true");
assertEval("double x() { return 2.5; }", assertEval("double x() { return 2.5; }",
ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
assertEval("x();", "2.5"); assertEval("x();", "2.5");
Collection<TypeDeclSnippet> classes = getState().types(); identityMatch(getState().types(), c);
assertEquals(classes.size(), 1);
assertTrue(c == classes.iterator().next(), "Identity must not change");
assertEval("x() == 2.5;", "true"); assertEval("x() == 2.5;", "true");
assertEval("new A().a == 10.0;", "true"); assertEval("new A().a == 10.0;", "true");
assertActiveKeys(); assertActiveKeys();
@ -313,8 +315,8 @@ public class ReplaceTest extends KullaTesting {
Snippet assn = ste.snippet(); Snippet assn = ste.snippet();
DeclarationSnippet unsn = ((UnresolvedReferenceException) ste.exception()).getSnippet(); DeclarationSnippet unsn = ((UnresolvedReferenceException) ste.exception()).getSnippet();
assertEquals(unsn.name(), "A", "Wrong with unresolved"); assertEquals(unsn.name(), "A", "Wrong with unresolved");
assertEquals(getState().unresolvedDependencies(unsn).size(), 1, "Wrong size unresolved"); assertEquals(getState().unresolvedDependencies(unsn).count(), 1, "Wrong size unresolved");
assertEquals(getState().diagnostics(unsn).size(), 0, "Expected no diagnostics"); assertEquals(getState().diagnostics(unsn).count(), 0L, "Expected no diagnostics");
Snippet g = varKey(assertEval("int g = 10;", "10", Snippet g = varKey(assertEval("int g = 10;", "10",
added(VALID), added(VALID),

View File

@ -39,6 +39,7 @@ import jdk.jshell.Snippet.SubKind;
import jdk.jshell.SnippetEvent; import jdk.jshell.SnippetEvent;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import static java.util.stream.Collectors.toList;
import static jdk.jshell.Snippet.Status.*; import static jdk.jshell.Snippet.Status.*;
import static jdk.jshell.Snippet.SubKind.VAR_DECLARATION_SUBKIND; import static jdk.jshell.Snippet.SubKind.VAR_DECLARATION_SUBKIND;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
@ -331,7 +332,7 @@ public class VariablesTest extends KullaTesting {
//assertEquals(getState().source(snippet), src); //assertEquals(getState().source(snippet), src);
//assertEquals(snippet, undefKey); //assertEquals(snippet, undefKey);
assertEquals(getState().status(undefKey), RECOVERABLE_NOT_DEFINED); assertEquals(getState().status(undefKey), RECOVERABLE_NOT_DEFINED);
List<String> unr = getState().unresolvedDependencies((VarSnippet) undefKey); List<String> unr = getState().unresolvedDependencies((VarSnippet) undefKey).collect(toList());;
assertEquals(unr.size(), 1); assertEquals(unr.size(), 1);
assertEquals(unr.get(0), "class undefined"); assertEquals(unr.get(0), "class undefined");
assertVariables(variable("undefined", "d")); assertVariables(variable("undefined", "d"));