8167128: JShell: /drop of statement gives confusing output
authorrfield
Mon, 10 Oct 2016 18:41:12 -0700
changeset 41514 a75c2b869d8d
parent 41455 0875007901f7
child 41515 d7e0b56ddbe5
8167128: JShell: /drop of statement gives confusing output Reviewed-by: jlahoda
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties
langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/Key.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java
langtools/test/jdk/jshell/DropTest.java
langtools/test/jdk/jshell/IdGeneratorTest.java
langtools/test/jdk/jshell/IllegalArgumentExceptionTest.java
langtools/test/jdk/jshell/JShellStateClosedTest.java
langtools/test/jdk/jshell/KullaTesting.java
langtools/test/jdk/jshell/ReplaceTest.java
langtools/test/jdk/jshell/ToolCommandOptionTest.java
langtools/test/jdk/jshell/ToolSimpleTest.java
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Mon Oct 10 18:41:12 2016 -0700
@@ -73,7 +73,6 @@
 import jdk.jshell.JShell;
 import jdk.jshell.JShell.Subscription;
 import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
 import jdk.jshell.Snippet;
 import jdk.jshell.Snippet.Status;
 import jdk.jshell.SnippetEvent;
@@ -1137,10 +1136,9 @@
         return state.snippets();
     }
 
-    Stream<PersistentSnippet> dropableSnippets() {
+    Stream<Snippet> dropableSnippets() {
         return state.snippets()
-                .filter(sn -> state.status(sn).isActive() && sn instanceof PersistentSnippet)
-                .map(sn -> (PersistentSnippet) sn);
+                .filter(sn -> state.status(sn).isActive());
     }
 
     Stream<VarSnippet> allVarSnippets() {
@@ -1761,13 +1759,13 @@
             errormsg("jshell.err.drop.arg");
             return false;
         }
-        Stream<PersistentSnippet> stream = argsToSnippets(this::dropableSnippets, args);
+        Stream<Snippet> stream = argsToSnippets(this::dropableSnippets, args);
         if (stream == null) {
             // Snippet not found. Error already printed
             fluffmsg("jshell.msg.see.classes.etc");
             return false;
         }
-        List<PersistentSnippet> snippets = stream.collect(toList());
+        List<Snippet> snippets = stream.collect(toList());
         if (snippets.size() > args.size()) {
             // One of the args references more thean one snippet
             errormsg("jshell.err.drop.ambiguous");
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Mon Oct 10 18:41:12 2016 -0700
@@ -743,7 +743,7 @@
 /set format verbose result '{name} ==> {value}{post}'                                        added,modified,replaced-ok-primary    \n\
 \n\
 /set format verbose display '{result}{pre}created scratch variable {name} : {type}{post}'    expression-added,modified,replaced-primary    \n\
-/set format verbose display '{result}{pre}value of {name} : {type}{post}'                    varvalue-primary    \n\
+/set format verbose display '{result}{pre}value of {name} : {type}{post}'                    varvalue-added,modified,replaced-primary    \n\
 /set format verbose display '{result}{pre}assigned to {name} : {type}{post}'                 assignment-primary    \n\
 /set format verbose display '{result}{pre}{action} variable {name} : {type}{resolve}{post}'  varinit,vardecl    \n\
 /set format verbose display '{pre}{action} variable {name}{resolve}{post}'                   vardecl,varinit-notdefined    \n\
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Mon Oct 10 18:41:12 2016 -0700
@@ -521,10 +521,13 @@
 
     List<SnippetEvent> drop(Snippet si) {
         Unit c = new Unit(state, si);
-
-        Set<Unit> ins = c.dependents().collect(toSet());
-        Set<Unit> outs = compileAndLoad(ins);
-
+        Set<Unit> outs;
+        if (si instanceof PersistentSnippet) {
+            Set<Unit> ins = c.dependents().collect(toSet());
+            outs = compileAndLoad(ins);
+        } else {
+            outs = Collections.emptySet();
+        }
         return events(c, outs, null, null);
     }
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Mon Oct 10 18:41:12 2016 -0700
@@ -58,7 +58,7 @@
  * API.  A {@code JShell} instance holds the evolving compilation and
  * execution state.  The state is changed with the instance methods
  * {@link jdk.jshell.JShell#eval(java.lang.String) eval(String)},
- * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet) drop(PersistentSnippet)} and
+ * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet) drop(Snippet)} and
  * {@link jdk.jshell.JShell#addToClasspath(java.lang.String) addToClasspath(String)}.
  * The majority of methods query the state.
  * A {@code JShell} instance also allows registering for events with
@@ -428,7 +428,12 @@
     }
 
     /**
-     * Remove a declaration from the state.
+     * Remove a declaration from the state.  That is, if the snippet is an
+     * {@linkplain jdk.jshell.Snippet.Status#isActive() active}
+     * {@linkplain jdk.jshell.PersistentSnippet persistent} snippet, remove the
+     * snippet and update the JShell evaluation state accordingly.
+     * For all active snippets, change the {@linkplain #status status} to
+     * {@link jdk.jshell.Snippet.Status#DROPPED DROPPED}.
      * @param snippet The snippet to remove
      * @return The list of events from updating declarations dependent on the
      * dropped snippet.
@@ -436,7 +441,7 @@
      * @throws IllegalArgumentException if the snippet is not associated with
      * this {@code JShell} instance.
      */
-    public List<SnippetEvent> drop(PersistentSnippet snippet) throws IllegalStateException {
+    public List<SnippetEvent> drop(Snippet snippet) throws IllegalStateException {
         checkIfAlive();
         checkValidSnippet(snippet);
         List<SnippetEvent> events = eval.drop(snippet);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Key.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Key.java	Mon Oct 10 18:41:12 2016 -0700
@@ -74,7 +74,7 @@
     /**
      * Grouping for snippets which persist and influence future code.
      * They are keyed off at least the name.  They may be Modified/Replaced
-     * with new input and can be dropped (JShell#drop).
+     * with new input.
      */
     static abstract class PersistentKey extends Key {
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java	Mon Oct 10 18:41:12 2016 -0700
@@ -28,8 +28,8 @@
 /**
  * Grouping for Snippets which persist and influence future code.
  * A persistent snippet can be
- * {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwritten)}
- * with new input and can be dropped {@link JShell#drop}.
+ * {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwritten}
+ * with new input.
  * <p>
  * <code>PersistentSnippet</code> is immutable: an access to
  * any of its methods will always return the same result.
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java	Mon Oct 10 18:41:12 2016 -0700
@@ -443,9 +443,7 @@
 
         /**
          * The snippet is inactive because of an explicit call to
-         * the {@link JShell#drop(PersistentSnippet)}.
-         * Only a {@link jdk.jshell.PersistentSnippet} can have this
-         * {@code Status}.
+         * the {@link JShell#drop(Snippet)}.
          * <p>
          * The snippet is not visible to other snippets
          * ({@link Status#isDefined() isDefined() == false})
@@ -525,10 +523,11 @@
 
         /**
          * Indicates whether the Snippet is active, that is,
-         * will the snippet be re-evaluated when a new
+         * will a {@linkplain jdk.jshell.PersistentSnippet persistent}
+         * snippet be re-evaluated when a new
          * {@link JShell#eval(java.lang.String) JShell.eval(String)} or
-         * {@link JShell#drop(jdk.jshell.PersistentSnippet)
-         * JShell.drop(PersistentSnippet)} that could change
+         * {@link JShell#drop(jdk.jshell.Snippet)
+         * JShell.drop(Snippet)} that could change
          * its status is invoked.  This is more broad than
          * {@link Status#isDefined()} since a Snippet which is
          * {@link Status#RECOVERABLE_NOT_DEFINED}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java	Mon Oct 10 18:41:12 2016 -0700
@@ -30,7 +30,7 @@
 /**
  * A description of a change to a Snippet. These are generated by direct changes
  * to state with {@link JShell#eval(java.lang.String) JShell.eval(String)} or
- * {@link JShell#drop(jdk.jshell.PersistentSnippet) JShell.drop(PersistentSnippet)},
+ * {@link JShell#drop(jdk.jshell.Snippet) JShell.drop(Snippet)},
  * or indirectly by these same methods as
  * dependencies change or Snippets are overwritten. For direct changes, the
  * {@link SnippetEvent#causeSnippet()} is {@code null}.
@@ -108,7 +108,7 @@
      * creation of a new Snippet via
      * {@link jdk.jshell.JShell#eval(java.lang.String) eval} or it is the
      * explicit drop of a Snippet with
-     * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet) drop}.
+     * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet) drop}.
      *
      * @return the Snippet which caused this change or {@code null} if
      * directly caused by an API action.
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java	Mon Oct 10 18:41:12 2016 -0700
@@ -46,7 +46,7 @@
  * {@link jdk.jshell.SnippetEvent}.  There are three major kinds of
  * changes to the status of a snippet: it can created with <code>eval</code>,
  * it can be dropped from the active source state with
- * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet)}, and it can have
+ * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet)}, and it can have
  * its status updated as a result of a status change in another snippet.
  * For
  * example: given <code>js</code>, an instance of <code>JShell</code>, executing
--- a/langtools/test/jdk/jshell/DropTest.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/test/jdk/jshell/DropTest.java	Mon Oct 10 18:41:12 2016 -0700
@@ -23,14 +23,14 @@
 
 /*
  * @test
- * @bug 8081431 8080069
+ * @bug 8081431 8080069 8167128
  * @summary Test of JShell#drop().
  * @build KullaTesting TestingInputStream
  * @run testng DropTest
  */
 
 import jdk.jshell.DeclarationSnippet;
-import jdk.jshell.PersistentSnippet;
+import jdk.jshell.Snippet;
 import jdk.jshell.VarSnippet;
 import org.testng.annotations.Test;
 
@@ -40,9 +40,9 @@
 public class DropTest extends KullaTesting {
 
     public void testDrop() {
-        PersistentSnippet var = varKey(assertEval("int x;"));
-        PersistentSnippet method = methodKey(assertEval("int mu() { return x * 4; }"));
-        PersistentSnippet clazz = classKey(assertEval("class C { String v() { return \"#\" + mu(); } }"));
+        Snippet var = varKey(assertEval("int x;"));
+        Snippet method = methodKey(assertEval("int mu() { return x * 4; }"));
+        Snippet clazz = classKey(assertEval("class C { String v() { return \"#\" + mu(); } }"));
         assertDrop(var,
                 ste(var, VALID, DROPPED, true, null),
                 ste(method, VALID, RECOVERABLE_DEFINED, false, var));
@@ -62,7 +62,7 @@
         assertEval("int x = 10;", "10",
                 added(VALID),
                 ste(method, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET));
-        PersistentSnippet c0 = varKey(assertEval("C c0 = new C();"));
+        Snippet c0 = varKey(assertEval("C c0 = new C();"));
         assertEval("c0.v();", "\"#40\"");
         assertEval("C c = new C();",
                 ste(MAIN_SNIPPET, VALID, VALID, false, null),
@@ -88,8 +88,8 @@
     }
 
     public void testDropImport() {
-        PersistentSnippet imp = importKey(assertEval("import java.util.*;"));
-        PersistentSnippet decl = varKey(
+        Snippet imp = importKey(assertEval("import java.util.*;"));
+        Snippet decl = varKey(
                 assertEval("List<Integer> list = Arrays.asList(1, 2, 3);", "[1, 2, 3]"));
         assertEval("list;", "[1, 2, 3]");
         assertDrop(imp,
@@ -100,8 +100,13 @@
         assertDeclareFail("list;", "compiler.err.cant.resolve.location");
     }
 
+    public void testDropStatement() {
+        Snippet x = key(assertEval("if (true);"));
+        assertDrop(x, ste(x, VALID, DROPPED, true, null));
+    }
+
     public void testDropVarToMethod() {
-        PersistentSnippet x = varKey(assertEval("int x;"));
+        Snippet x = varKey(assertEval("int x;"));
         DeclarationSnippet method = methodKey(assertEval("double mu() { return x * 4; }"));
         assertEval("x == 0;", "true");
         assertEval("mu() == 0.0;", "true");
@@ -118,7 +123,7 @@
     }
 
     public void testDropMethodToMethod() {
-        PersistentSnippet a = methodKey(assertEval("double a() { return 2; }"));
+        Snippet a = methodKey(assertEval("double a() { return 2; }"));
         DeclarationSnippet b = methodKey(assertEval("double b() { return a() * 10; }"));
         assertEval("double c() { return b() * 3; }");
         DeclarationSnippet d = methodKey(assertEval("double d() { return c() + 1000; }"));
@@ -134,7 +139,7 @@
     }
 
     public void testDropClassToMethod() {
-        PersistentSnippet c = classKey(assertEval("class C { int f() { return 7; } }"));
+        Snippet c = classKey(assertEval("class C { int f() { return 7; } }"));
         DeclarationSnippet m = methodKey(assertEval("int m() { return new C().f(); }"));
         assertDrop(c,
                 ste(c, VALID, DROPPED, true, null),
@@ -145,7 +150,7 @@
     }
 
     public void testDropVarToClass() {
-        PersistentSnippet x = varKey(assertEval("int x;"));
+        Snippet x = varKey(assertEval("int x;"));
         DeclarationSnippet a = classKey(assertEval("class A { double a = 4 * x; }"));
         assertDrop(x,
                 DiagCheck.DIAG_OK,
@@ -160,7 +165,7 @@
     }
 
     public void testDropMethodToClass() {
-        PersistentSnippet x = methodKey(assertEval("int x() { return 0; }"));
+        Snippet x = methodKey(assertEval("int x() { return 0; }"));
         DeclarationSnippet a = classKey(assertEval("class A { double a = 4 * x(); }"));
         assertDrop(x,
                 DiagCheck.DIAG_OK,
@@ -174,10 +179,10 @@
     }
 
     public void testDropClassToClass() {
-        PersistentSnippet a = classKey(assertEval("class A {}"));
-        PersistentSnippet b = classKey(assertEval("class B extends A {}"));
-        PersistentSnippet c = classKey(assertEval("class C extends B {}"));
-        PersistentSnippet d = classKey(assertEval("class D extends C {}"));
+        Snippet a = classKey(assertEval("class A {}"));
+        Snippet b = classKey(assertEval("class B extends A {}"));
+        Snippet c = classKey(assertEval("class C extends B {}"));
+        Snippet d = classKey(assertEval("class D extends C {}"));
         assertDrop(a,
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
@@ -201,9 +206,9 @@
     public void testDropNoUpdate() {
         String as1 = "class A {}";
         String as2 = "class A extends java.util.ArrayList<Boolean> {}";
-        PersistentSnippet a = classKey(assertEval(as1, added(VALID)));
-        PersistentSnippet b = classKey(assertEval("class B extends A {}", added(VALID)));
-        PersistentSnippet ax = classKey(assertEval(as2,
+        Snippet a = classKey(assertEval(as1, added(VALID)));
+        Snippet b = classKey(assertEval("class B extends A {}", added(VALID)));
+        Snippet ax = classKey(assertEval(as2,
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
                 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
                 ste(b, VALID, VALID, true, MAIN_SNIPPET)));
--- a/langtools/test/jdk/jshell/IdGeneratorTest.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/test/jdk/jshell/IdGeneratorTest.java	Mon Oct 10 18:41:12 2016 -0700
@@ -35,7 +35,6 @@
 
 import jdk.jshell.EvalException;
 import jdk.jshell.JShell;
-import jdk.jshell.PersistentSnippet;
 import jdk.jshell.SnippetEvent;
 import jdk.jshell.UnresolvedReferenceException;
 import jdk.jshell.VarSnippet;
@@ -88,7 +87,7 @@
         try (JShell jShell = builder.build()) {
             List<SnippetEvent> eval = jShell.eval("int a, b;");
             checkIds(eval);
-            checkIds(jShell.drop((PersistentSnippet) eval.get(0).snippet()));
+            checkIds(jShell.drop(eval.get(0).snippet()));
         }
     }
 
--- a/langtools/test/jdk/jshell/IllegalArgumentExceptionTest.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/test/jdk/jshell/IllegalArgumentExceptionTest.java	Mon Oct 10 18:41:12 2016 -0700
@@ -31,7 +31,6 @@
 import java.util.function.Consumer;
 
 import jdk.jshell.DeclarationSnippet;
-import jdk.jshell.PersistentSnippet;
 import jdk.jshell.Snippet;
 import jdk.jshell.VarSnippet;
 import org.testng.annotations.Test;
@@ -64,7 +63,7 @@
     }
 
     public void testDrop() {
-        testIllegalArgumentException((key) -> getState().drop((PersistentSnippet) key));
+        testIllegalArgumentException((key) -> getState().drop(key));
     }
 
     public void testUnresolved() {
--- a/langtools/test/jdk/jshell/JShellStateClosedTest.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/test/jdk/jshell/JShellStateClosedTest.java	Mon Oct 10 18:41:12 2016 -0700
@@ -33,7 +33,6 @@
 import jdk.jshell.DeclarationSnippet;
 import jdk.jshell.ImportSnippet;
 import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
 import jdk.jshell.Snippet;
 import jdk.jshell.TypeDeclSnippet;
 import jdk.jshell.VarSnippet;
@@ -127,7 +126,7 @@
     }
 
     public void testDrop() {
-        testStateClosedException((key) -> getState().drop((PersistentSnippet) key));
+        testStateClosedException((key) -> getState().drop(key));
     }
 
     public void testUnresolved() {
--- a/langtools/test/jdk/jshell/KullaTesting.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/test/jdk/jshell/KullaTesting.java	Mon Oct 10 18:41:12 2016 -0700
@@ -54,7 +54,6 @@
 import jdk.jshell.ImportSnippet;
 import jdk.jshell.Snippet.Kind;
 import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
 import jdk.jshell.Snippet.Status;
 import jdk.jshell.Snippet.SubKind;
 import jdk.jshell.TypeDeclSnippet;
@@ -733,15 +732,15 @@
         assertEquals(expectedSubKind.kind(), expectedKind, "Checking kind: ");
     }
 
-    public void assertDrop(PersistentSnippet key, STEInfo mainInfo, STEInfo... updates) {
+    public void assertDrop(Snippet key, STEInfo mainInfo, STEInfo... updates) {
         assertDrop(key, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, mainInfo, updates);
     }
 
-    public void assertDrop(PersistentSnippet key, DiagCheck diagMain, DiagCheck diagUpdates, STEInfo mainInfo, STEInfo... updates) {
+    public void assertDrop(Snippet key, DiagCheck diagMain, DiagCheck diagUpdates, STEInfo mainInfo, STEInfo... updates) {
         assertDrop(key, diagMain, diagUpdates, new EventChain(mainInfo, null, null, updates));
     }
 
-    public void assertDrop(PersistentSnippet key, DiagCheck diagMain, DiagCheck diagUpdates, EventChain... eventChains) {
+    public void assertDrop(Snippet key, DiagCheck diagMain, DiagCheck diagUpdates, EventChain... eventChains) {
         checkEvents(() -> getState().drop(key), "drop(" + key + ")", diagMain, diagUpdates, eventChains);
     }
 
--- a/langtools/test/jdk/jshell/ReplaceTest.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/test/jdk/jshell/ReplaceTest.java	Mon Oct 10 18:41:12 2016 -0700
@@ -33,7 +33,6 @@
 import java.util.stream.Stream;
 import jdk.jshell.Snippet;
 import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
 import jdk.jshell.TypeDeclSnippet;
 import jdk.jshell.VarSnippet;
 import jdk.jshell.DeclarationSnippet;
@@ -585,14 +584,14 @@
     }
 
     public void testForwardSingleImportMethodToClass1() {
-        PersistentSnippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
+        Snippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
                 added(RECOVERABLE_DEFINED)));
         assertEvalUnresolvedException("new A();", "A", 1, 0);
         assertEval("import static java.lang.String.format;",
                 added(VALID),
                 ste(a, RECOVERABLE_DEFINED, VALID, false, null));
         assertEval("new A().s;", "\"10\"");
-        PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+        Snippet format = methodKey(assertEval("void format(String s, int d) { }",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -605,14 +604,14 @@
     }
 
     public void testForwardSingleImportMethodToClass2() {
-        PersistentSnippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
+        Snippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
                 added(RECOVERABLE_DEFINED)));
         assertEvalUnresolvedException("new A();", "A", 1, 0);
         assertEval("import static java.lang.String.format;",
                 added(VALID),
                 ste(a, RECOVERABLE_DEFINED, VALID, false, null));
         assertEval("new A().s();", "\"10\"");
-        PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+        Snippet format = methodKey(assertEval("void format(String s, int d) { }",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -625,7 +624,7 @@
     }
 
     public void testForwardSingleImportClassToClass1() {
-        PersistentSnippet a = classKey(assertEval("class A { static List<Integer> list; }",
+        Snippet a = classKey(assertEval("class A { static List<Integer> list; }",
                 added(RECOVERABLE_NOT_DEFINED)));
         assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
         assertEval("import java.util.List;",
@@ -634,7 +633,7 @@
         assertEval("import java.util.Arrays;", added(VALID));
         assertEval("A.list = Arrays.asList(1, 2, 3);", "[1, 2, 3]");
 
-        PersistentSnippet list = classKey(assertEval("class List {}",
+        Snippet list = classKey(assertEval("class List {}",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -647,7 +646,7 @@
     }
 
     public void testForwardSingleImportClassToClass2() {
-        PersistentSnippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
+        Snippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
                 added(RECOVERABLE_NOT_DEFINED)));
         assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
         assertEval("import java.util.ArrayList;",
@@ -655,7 +654,7 @@
                 ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET));
         Snippet vara = varKey(assertEval("A a = new A();", "[]"));
 
-        PersistentSnippet arraylist = classKey(assertEval("class ArrayList {}",
+        Snippet arraylist = classKey(assertEval("class ArrayList {}",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -671,7 +670,7 @@
     }
 
     public void testForwardImportOnDemandMethodToClass1() {
-        PersistentSnippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
+        Snippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
                 added(RECOVERABLE_DEFINED)));
         assertEvalUnresolvedException("new A();", "A", 1, 0);
         assertEval("import static java.lang.String.*;",
@@ -679,7 +678,7 @@
                 ste(a, RECOVERABLE_DEFINED, VALID, false, null));
         assertEval("A x = new A();");
         assertEval("x.s;", "\"10\"");
-        PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+        Snippet format = methodKey(assertEval("void format(String s, int d) { }",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -693,14 +692,14 @@
     }
 
     public void testForwardImportOnDemandMethodToClass2() {
-        PersistentSnippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
+        Snippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
                 added(RECOVERABLE_DEFINED)));
         assertEvalUnresolvedException("new A();", "A", 1, 0);
         assertEval("import static java.lang.String.*;",
                 added(VALID),
                 ste(a, RECOVERABLE_DEFINED, VALID, false, null));
         assertEval("new A().s();", "\"10\"");
-        PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+        Snippet format = methodKey(assertEval("void format(String s, int d) { }",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -713,7 +712,7 @@
     }
 
     public void testForwardImportOnDemandClassToClass1() {
-        PersistentSnippet a = classKey(assertEval("class A { static List<Integer> list; }",
+        Snippet a = classKey(assertEval("class A { static List<Integer> list; }",
                 added(RECOVERABLE_NOT_DEFINED)));
         assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
         assertEval("import java.util.*;",
@@ -721,7 +720,7 @@
                 ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
         assertEval("A.list = Arrays.asList(1, 2, 3);", "[1, 2, 3]");
 
-        PersistentSnippet list = classKey(assertEval("class List {}",
+        Snippet list = classKey(assertEval("class List {}",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -734,7 +733,7 @@
     }
 
     public void testForwardImportOnDemandClassToClass2() {
-        PersistentSnippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
+        Snippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
                 added(RECOVERABLE_NOT_DEFINED)));
         assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
         assertEval("import java.util.*;",
@@ -742,7 +741,7 @@
                 ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET));
         Snippet vara = varKey(assertEval("A a = new A();", "[]"));
 
-        PersistentSnippet arraylist = classKey(assertEval("class ArrayList {}",
+        Snippet arraylist = classKey(assertEval("class ArrayList {}",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -757,7 +756,7 @@
     }
 
     public void testForwardSingleImportFieldToClass1() {
-        PersistentSnippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
+        Snippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
                 added(RECOVERABLE_DEFINED)));
         assertEvalUnresolvedException("new A();", "A", 1, 0);
         assertEval("import static java.lang.Math.PI;",
@@ -765,7 +764,7 @@
                 ste(a, RECOVERABLE_DEFINED, VALID, false, null));
         assertEval("Math.abs(A.pi() - 3.1415) < 0.001;", "true");
 
-        PersistentSnippet list = varKey(assertEval("String PI;",
+        Snippet list = varKey(assertEval("String PI;",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -778,7 +777,7 @@
     }
 
     public void testForwardSingleImportFieldToClass2() {
-        PersistentSnippet a = classKey(assertEval("class A { static double pi = PI; }",
+        Snippet a = classKey(assertEval("class A { static double pi = PI; }",
                 added(RECOVERABLE_DEFINED)));
         assertEvalUnresolvedException("new A();", "A", 1, 0);
         assertEval("import static java.lang.Math.PI;",
@@ -786,7 +785,7 @@
                 ste(a, RECOVERABLE_DEFINED, VALID, true, null));
         assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true");
 
-        PersistentSnippet list = varKey(assertEval("String PI;",
+        Snippet list = varKey(assertEval("String PI;",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -799,7 +798,7 @@
     }
 
     public void testForwardImportOnDemandFieldToClass1() {
-        PersistentSnippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
+        Snippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
                 added(RECOVERABLE_DEFINED)));
         assertEvalUnresolvedException("new A();", "A", 1, 0);
         assertEval("import static java.lang.Math.*;",
@@ -807,7 +806,7 @@
                 ste(a, RECOVERABLE_DEFINED, VALID, false, null));
         assertEval("Math.abs(A.pi() - 3.1415) < 0.001;", "true");
 
-        PersistentSnippet list = varKey(assertEval("String PI;",
+        Snippet list = varKey(assertEval("String PI;",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
@@ -820,7 +819,7 @@
     }
 
     public void testForwardImportOnDemandFieldToClass2() {
-        PersistentSnippet a = classKey(assertEval("class A { static double pi = PI; }",
+        Snippet a = classKey(assertEval("class A { static double pi = PI; }",
                 added(RECOVERABLE_DEFINED)));
         assertEvalUnresolvedException("new A();", "A", 1, 0);
         assertEval("import static java.lang.Math.*;",
@@ -828,7 +827,7 @@
                 ste(a, RECOVERABLE_DEFINED, VALID, true, null));
         assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true");
 
-        PersistentSnippet list = varKey(assertEval("String PI;",
+        Snippet list = varKey(assertEval("String PI;",
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
                 added(VALID),
--- a/langtools/test/jdk/jshell/ToolCommandOptionTest.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java	Mon Oct 10 18:41:12 2016 -0700
@@ -23,7 +23,7 @@
 
  /*
  * @test
- * @bug 8157395 8157393 8157517 8158738
+ * @bug 8157395 8157393 8157517 8158738  8167128
  * @summary Tests of jshell comand options, and undoing operations
  * @modules jdk.jshell/jdk.internal.jshell.tool
  * @build ToolCommandOptionTest ReplToolTesting
@@ -101,13 +101,17 @@
                         "|  Unknown option: -all -- /drop -all"),
                 (a) -> assertCommandOutputStartsWith(a, "/drop z",
                         "|  No such snippet: z"),
-                (a) -> assertCommandOutputStartsWith(a, "/drop 2",
-                        "|  This command does not accept the snippet '2' : x"),
+                (a) -> assertCommand(a, "/drop 2",
+                        ""),
+                (a) -> assertCommandOutputStartsWith(a, "23qwl",
+                        "|  Error:"),
+                (a) -> assertCommandOutputStartsWith(a, "/drop e1",
+                        "|  This command does not accept the snippet 'e1' : 23qwl"),
                 (a) -> assertCommand(a, "/dr x y",
                         "|  dropped variable x\n" +
                         "|  dropped variable y"),
                 (a) -> assertCommand(a, "/list",
-                        "2 : x")
+                        "")
         );
     }
 
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java	Wed Jul 05 22:19:47 2017 +0200
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java	Mon Oct 10 18:41:12 2016 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897
+ * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128
  * @summary Simple jshell tool tests
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -217,6 +217,9 @@
                 a -> dropClass(a, "/drop 3", "class A", "|  dropped class A"),
                 a -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
                 a -> dropImport(a, "/drop 4", "import java.util.stream.*", ""),
+                a -> assertCommand(a, "for (int i = 0; i < 10; ++i) {}", ""),
+                a -> assertCommand(a, "/drop 5", ""),
+                a -> assertCommand(a, "/list", ""),
                 a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
                 a -> assertCommandCheckOutput(a, "/methods", assertMethods()),
                 a -> assertCommandCheckOutput(a, "/types", assertClasses()),
@@ -244,6 +247,7 @@
                         assertStartsWith("|  In the /drop argument, please specify an import, variable, method, or class to drop.")),
                 a -> assertVariable(a, "int", "a"),
                 a -> assertCommand(a, "a", "a ==> 0"),
+                a -> assertCommand(a, "/drop 2", ""),
                 a -> assertCommand(a, "/drop 2",
                         "|  This command does not accept the snippet '2' : a\n" +
                         "|  See /types, /methods, /vars, or /list")