diff -r 4ebc2e2fb97c -r 71c04702a3d5 test/langtools/jdk/jshell/VariablesTest.java --- /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[][] get() { return null; } }", added(VALID)); + assertEval("Test 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 list = new ArrayList<>();", "[]", + added(VALID))); + assertVariables(variable("List", "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 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 unr = getState().unresolvedDependencies((VarSnippet) undefKey).collect(toList());; + assertEquals(unr.size(), 1); + assertEquals(unr.get(0), "class undefined"); + assertVariables(variable("undefined", "d")); + } +}