test/langtools/jdk/jshell/VariablesTest.java
changeset 47216 71c04702a3d5
parent 43134 006808ae5f6e
child 47268 48ec75306997
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/jshell/VariablesTest.java	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2015, 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 8144903
+ * @summary Tests for EvaluationState.variables
+ * @build KullaTesting TestingInputStream ExpectedDiagnostic
+ * @run testng VariablesTest
+ */
+
+import java.util.List;
+import javax.tools.Diagnostic;
+
+import jdk.jshell.Snippet;
+import jdk.jshell.TypeDeclSnippet;
+import jdk.jshell.VarSnippet;
+import jdk.jshell.Snippet.SubKind;
+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;
+import static org.testng.Assert.fail;
+
+@Test
+public class VariablesTest extends KullaTesting {
+
+    public void noVariables() {
+        assertNumberOfActiveVariables(0);
+    }
+
+    private void badVarValue(VarSnippet key) {
+        try {
+            getState().varValue(key);
+            fail("Expected exception for: " + key.source());
+        } catch (IllegalArgumentException e) {
+            // ok
+        }
+    }
+
+    public void testVarValue1() {
+        VarSnippet v1 = varKey(assertEval("und1 a;", added(RECOVERABLE_NOT_DEFINED)));
+        badVarValue(v1);
+        VarSnippet v2 = varKey(assertEval("und2 a;",
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null),
+                ste(v1, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET)));
+        badVarValue(v2);
+        TypeDeclSnippet und = classKey(assertEval("class und2 {}",
+                added(VALID),
+                ste(v2, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET)));
+        assertVarValue(v2, "null");
+        assertDrop(und,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(und, VALID, DROPPED, true, null),
+                ste(v2, VALID, RECOVERABLE_NOT_DEFINED, true, und));
+        badVarValue(v1);
+        badVarValue(v2);
+    }
+
+    public void testVarValue2() {
+        VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
+        badVarValue(v1);
+        VarSnippet v2 = varKey(assertEval("int a = 0;", added(VALID)));
+        assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
+        badVarValue(v2);
+    }
+
+    public void testSignature1() {
+        VarSnippet v1 = varKey(assertEval("und1 a;", added(RECOVERABLE_NOT_DEFINED)));
+        assertVariableDeclSnippet(v1, "a", "und1", RECOVERABLE_NOT_DEFINED, VAR_DECLARATION_SUBKIND, 1, 0);
+        VarSnippet v2 = varKey(assertEval("und2 a;",
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null),
+                ste(v1, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertVariableDeclSnippet(v2, "a", "und2", RECOVERABLE_NOT_DEFINED, VAR_DECLARATION_SUBKIND, 1, 0);
+        TypeDeclSnippet und = classKey(assertEval("class und2 {}",
+                added(VALID),
+                ste(v2, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET)));
+        assertVariableDeclSnippet(v2, "a", "und2", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
+        assertDrop(und,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(und, VALID, DROPPED, true, null),
+                ste(v2, VALID, RECOVERABLE_NOT_DEFINED, true, und));
+        assertVariableDeclSnippet(v2, "a", "und2", RECOVERABLE_NOT_DEFINED, VAR_DECLARATION_SUBKIND, 1, 0);
+    }
+
+    public void testSignature2() {
+        VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
+        assertVariableDeclSnippet(v1, "a", "int", REJECTED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 1);
+        VarSnippet v2 = varKey(assertEval("int a = 0;",
+                added(VALID)));
+        assertVariableDeclSnippet(v2, "a", "int", VALID, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
+        assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
+        assertVariableDeclSnippet(v2, "a", "int", DROPPED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
+    }
+
+    public void variables() {
+        VarSnippet snx = varKey(assertEval("int x = 10;"));
+        VarSnippet sny = varKey(assertEval("String y = \"hi\";"));
+        VarSnippet snz = varKey(assertEval("long z;"));
+        assertVariables(variable("int", "x"), variable("String", "y"), variable("long", "z"));
+        assertVarValue(snx, "10");
+        assertVarValue(sny, "\"hi\"");
+        assertVarValue(snz, "0");
+        assertActiveKeys();
+    }
+
+    public void variablesArray() {
+        VarSnippet sn = varKey(assertEval("int[] a = new int[12];"));
+        assertEquals(sn.typeName(), "int[]");
+        assertEval("int len = a.length;", "12");
+        assertVariables(variable("int[]", "a"), variable("int", "len"));
+        assertActiveKeys();
+    }
+
+    public void variablesArrayOld() {
+        VarSnippet sn = varKey(assertEval("int a[] = new int[12];"));
+        assertEquals(sn.typeName(), "int[]");
+        assertEval("int len = a.length;", "12");
+        assertVariables(variable("int[]", "a"), variable("int", "len"));
+        assertActiveKeys();
+    }
+
+    public void variablesRedefinition() {
+        Snippet x = varKey(assertEval("int x = 10;"));
+        Snippet y = varKey(assertEval("String y = \"\";", added(VALID)));
+        assertVariables(variable("int", "x"), variable("String", "y"));
+        assertActiveKeys();
+        assertEval("long x;",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertVariables(variable("long", "x"), variable("String", "y"));
+        assertActiveKeys();
+        assertEval("String y;",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(y, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertVariables(variable("long", "x"), variable("String", "y"));
+        assertActiveKeys();
+    }
+
+    public void variablesTemporary() {
+        assertEval("int $1 = 10;", added(VALID));
+        assertEval("2 * $1;", added(VALID));
+        assertVariables(variable("int", "$1"), variable("int", "$2"));
+        assertActiveKeys();
+        assertEval("String y;", added(VALID));
+        assertVariables(variable("int", "$1"), variable("int", "$2"), variable("String", "y"));
+        assertActiveKeys();
+    }
+
+    public void variablesTemporaryNull() {
+        assertEval("null;", added(VALID));
+        assertVariables(variable("Object", "$1"));
+        assertEval("(String) null;", added(VALID));
+        assertVariables(variable("Object", "$1"), variable("String", "$2"));
+        assertActiveKeys();
+        assertEval("\"\";", added(VALID));
+        assertVariables(
+                variable("Object", "$1"),
+                variable("String", "$2"),
+                variable("String", "$3"));
+        assertActiveKeys();
+    }
+
+    public void variablesTemporaryArrayOfCapturedType() {
+        assertEval("class Test<T> { T[][] get() { return null; } }", added(VALID));
+        assertEval("Test<? extends String> test() { return new Test<>(); }", added(VALID));
+        assertEval("test().get()", added(VALID));
+        assertVariables(variable("String[][]", "$1"));
+        assertEval("\"\".getClass().getEnumConstants()", added(VALID));
+        assertVariables(variable("String[][]", "$1"), variable("String[]", "$2"));
+        assertActiveKeys();
+    }
+
+    public void variablesClassReplace() {
+        assertEval("import java.util.*;", added(VALID));
+        Snippet var = varKey(assertEval("List<Integer> list = new ArrayList<>();", "[]",
+                added(VALID)));
+        assertVariables(variable("List<Integer>", "list"));
+        assertEval("class List {}",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(var, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET));
+        assertVariables();
+        assertEval("List list = new List();",
+                DiagCheck.DIAG_OK, DiagCheck.DIAG_IGNORE,
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, VALID, true, null),
+                ste(var, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertVariables(variable("List", "list"));
+        assertActiveKeys();
+    }
+
+    public void variablesErrors() {
+        assertDeclareFail("String;", new ExpectedDiagnostic("compiler.err.cant.resolve.location", 0, 6, 0, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveVariables(0);
+        assertActiveKeys();
+    }
+
+    public void variablesUnresolvedActiveFailed() {
+        VarSnippet key = varKey(assertEval("und x;", added(RECOVERABLE_NOT_DEFINED)));
+        assertVariableDeclSnippet(key, "x", "und", RECOVERABLE_NOT_DEFINED, VAR_DECLARATION_SUBKIND, 1, 0);
+        assertUnresolvedDependencies1(key, RECOVERABLE_NOT_DEFINED, "class und");
+        assertNumberOfActiveVariables(1);
+        assertActiveKeys();
+    }
+
+    public void variablesUnresolvedError() {
+        assertDeclareFail("und y = null;", new ExpectedDiagnostic("compiler.err.cant.resolve.location", 0, 3, 0, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveVariables(0);
+        assertActiveKeys();
+    }
+
+    public void variablesMultiByteCharacterType() {
+        assertEval("class \u3042 {}");
+        assertEval("\u3042 \u3042 = null;", added(VALID));
+        assertVariables(variable("\u3042", "\u3042"));
+        assertEval("new \u3042()", added(VALID));
+        assertVariables(variable("\u3042", "\u3042"), variable("\u3042", "$1"));
+
+        assertEval("class \u3042\u3044\u3046\u3048\u304a {}");
+        assertEval("\u3042\u3044\u3046\u3048\u304a \u3042\u3044\u3046\u3048\u304a = null;", added(VALID));
+        assertVariables(variable("\u3042", "\u3042"), variable("\u3042", "$1"),
+                variable("\u3042\u3044\u3046\u3048\u304a", "\u3042\u3044\u3046\u3048\u304a"));
+        assertEval("new \u3042\u3044\u3046\u3048\u304a();");
+        assertVariables(variable("\u3042", "\u3042"), variable("\u3042", "$1"),
+                variable("\u3042\u3044\u3046\u3048\u304a", "\u3042\u3044\u3046\u3048\u304a"),
+                variable("\u3042\u3044\u3046\u3048\u304a", "$2"));
+        assertActiveKeys();
+    }
+
+    @Test(enabled = false) // TODO 8081689
+    public void methodVariablesAreNotVisible() {
+        Snippet foo = varKey(assertEval("int foo() {" +
+                        "int x = 10;" +
+                        "int y = 2 * x;" +
+                        "return x * y;" +
+                        "}", added(VALID)));
+        assertNumberOfActiveVariables(0);
+        assertActiveKeys();
+        assertEval("int x = 10;", "10");
+        assertEval("int foo() {" +
+                        "int y = 2 * x;" +
+                        "return x * y;" +
+                        "}",
+                ste(foo, VALID, VALID, false, null));
+        assertVariables(variable("int", "x"));
+        assertActiveKeys();
+        assertEval("foo();", "200");
+        assertVariables(variable("int", "x"), variable("int", "$1"));
+        assertActiveKeys();
+    }
+
+    @Test(enabled = false) // TODO 8081689
+    public void classFieldsAreNotVisible() {
+        Snippet key = classKey(assertEval("class clazz {" +
+                        "int x = 10;" +
+                        "int y = 2 * x;" +
+                        "}"));
+        assertNumberOfActiveVariables(0);
+        assertEval("int x = 10;", "10");
+        assertActiveKeys();
+        assertEval(
+                "class clazz {" +
+                        "int y = 2 * x;" +
+                        "}",
+                ste(key, VALID, VALID, true, null));
+        assertVariables(variable("int", "x"));
+        assertEval("new clazz().y;", "20");
+        assertVariables(variable("int", "x"), variable("int", "$1"));
+        assertActiveKeys();
+    }
+
+    public void multiVariables() {
+        List<SnippetEvent> abc = assertEval("int a, b, c = 10;",
+                DiagCheck.DIAG_OK, DiagCheck.DIAG_OK,
+                chain(added(VALID)),
+                chain(added(VALID)),
+                chain(added(VALID)));
+        Snippet a = abc.get(0).snippet();
+        Snippet b = abc.get(1).snippet();
+        Snippet c = abc.get(2).snippet();
+        assertVariables(variable("int", "a"), variable("int", "b"), variable("int", "c"));
+        assertEval("double a = 1.4, b = 8.8;", DiagCheck.DIAG_OK, DiagCheck.DIAG_OK,
+                chain(ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET)),
+                chain(ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertVariables(variable("double", "a"), variable("double", "b"), variable("int", "c"));
+        assertEval("double c = a + b;",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertVariables(variable("double", "a"), variable("double", "b"), variable("double", "c"));
+        assertActiveKeys();
+    }
+
+    public void syntheticVariables() {
+        assertEval("assert false;");
+        assertNumberOfActiveVariables(0);
+        assertActiveKeys();
+    }
+
+    public void undefinedReplaceVariable() {
+        Snippet key = varKey(assertEval("int d = 234;", "234"));
+        assertVariables(variable("int", "d"));
+        String src = "undefined d;";
+        Snippet undefKey = varKey(assertEval(src,
+                ste(MAIN_SNIPPET, VALID, RECOVERABLE_NOT_DEFINED, true, null),
+                ste(key, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        //assertEquals(getState().source(snippet), src);
+        //assertEquals(snippet, undefKey);
+        assertEquals(getState().status(undefKey), RECOVERABLE_NOT_DEFINED);
+        List<String> unr = getState().unresolvedDependencies((VarSnippet) undefKey).collect(toList());;
+        assertEquals(unr.size(), 1);
+        assertEquals(unr.get(0), "class undefined");
+        assertVariables(variable("undefined", "d"));
+    }
+}