# HG changeset patch # User rfield # Date 1449861610 28800 # Node ID 36d62753f5daaa168f737410682dfbdea550871c # Parent 4edcff1b9a8875eb6380a2165dfec599e8e3f7c0 8144903: JShell: determine incorrectly the type of the expression which is array type of captured type Summary: Fix and clean-up the processing of types (esp. captured types) into type names for use in generated temp vars Reviewed-by: mcimadamore, jlahoda, rfield Contributed-by: bitterfoxc@gmail.com diff -r 4edcff1b9a88 -r 36d62753f5da langtools/src/jdk.jshell/share/classes/jdk/jshell/TypePrinter.java --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypePrinter.java Wed Jul 05 21:07:43 2017 +0200 +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypePrinter.java Fri Dec 11 11:20:10 2015 -0800 @@ -41,15 +41,15 @@ * Print types in source form. */ class TypePrinter extends Printer { + private static final String OBJECT = "Object"; private final JavacMessages messages; private final BinaryOperator fullClassNameAndPackageToClass; - private final Type typeToPrint; + private boolean useWildCard = false; TypePrinter(JavacMessages messages, BinaryOperator fullClassNameAndPackageToClass, Type typeToPrint) { this.messages = messages; this.fullClassNameAndPackageToClass = fullClassNameAndPackageToClass; - this.typeToPrint = typeToPrint; } @Override @@ -64,21 +64,40 @@ @Override public String visitCapturedType(Type.CapturedType t, Locale locale) { - if (t == typeToPrint) { - return visit(t.getUpperBound(), locale); - } else { - return visit(t.wildcard, locale); + return visit(t.wildcard, locale); + } + + @Override + public String visitWildcardType(Type.WildcardType wt, Locale locale) { + if (useWildCard) { // at TypeArgument(ex: List) + return super.visitWildcardType(wt, locale); + } else { // at TopLevelType(ex: ? extends List, ? extends Number[][]) + Type extendsBound = wt.getExtendsBound(); + return extendsBound == null + ? OBJECT + : visit(extendsBound, locale); } } @Override public String visitType(Type t, Locale locale) { String s = (t.tsym == null || t.tsym.name == null) - ? "Object" // none + ? OBJECT // none : t.tsym.name.toString(); return s; } + @Override + public String visitClassType(ClassType ct, Locale locale) { + boolean prevUseWildCard = useWildCard; + try { + useWildCard = true; + return super.visitClassType(ct, locale); + } finally { + useWildCard = prevUseWildCard; + } + } + /** * Converts a class name into a (possibly localized) string. Anonymous * inner classes get converted into a localized string. @@ -101,7 +120,7 @@ } return s.toString(); ***/ - return "Object"; + return OBJECT; } else if (sym.name.length() == 0) { // Anonymous String s; diff -r 4edcff1b9a88 -r 36d62753f5da langtools/test/jdk/jshell/TypeNameTest.java --- a/langtools/test/jdk/jshell/TypeNameTest.java Wed Jul 05 21:07:43 2017 +0200 +++ b/langtools/test/jdk/jshell/TypeNameTest.java Fri Dec 11 11:20:10 2015 -0800 @@ -23,7 +23,8 @@ /* * @test - * @summary null test + * @bug 8144903 + * @summary Tests for determining the type from the expression * @build KullaTesting TestingInputStream * @run testng TypeNameTest */ @@ -34,7 +35,6 @@ import static jdk.jshell.Snippet.Status.VALID; import static org.testng.Assert.assertEquals; -import static jdk.jshell.Snippet.Status.OVERWRITTEN; @Test public class TypeNameTest extends KullaTesting { @@ -62,6 +62,11 @@ assertEquals(sn.typeName(), "Class"); } + public void testArrayTypeOfCapturedTypeName() { + VarSnippet sn = (VarSnippet) varKey(assertEval("\"\".getClass().getEnumConstants();")); + assertEquals(sn.typeName(), "String[]"); + } + public void testJavaLang() { VarSnippet sn = (VarSnippet) varKey(assertEval("\"\";")); assertEquals(sn.typeName(), "String"); @@ -83,14 +88,16 @@ VarSnippet sn3 = (VarSnippet) varKey(assertEval("list3.iterator().next()")); assertEquals(sn3.typeName(), "Object"); assertEval("class Test1 { public X get() { return null; } }"); - Snippet x = varKey(assertEval("Test1 x = new Test1<>();")); - VarSnippet sn4 = (VarSnippet) varKey(assertEval("x.get()")); - assertEquals(sn4.typeName(), "CharSequence"); - assertEval("class Foo { public X get() { return null; } }"); - assertEval("Foo x = new Foo<>();", - ste(MAIN_SNIPPET, VALID, VALID, true, null), - ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); - VarSnippet sn5 = (VarSnippet) varKey(assertEval("x.get()")); + Snippet x = varKey(assertEval("Test1 test1 = new Test1<>();")); + VarSnippet sn4 = (VarSnippet) varKey(assertEval("test1.get()")); + assertEquals(sn4.typeName(), "Object"); + assertEval("class Test2 { public X get() { return null; } }"); + assertEval("Test2 test2 = new Test2<>();"); + VarSnippet sn5 = (VarSnippet) varKey(assertEval("test2.get()")); assertEquals(sn5.typeName(), "Object"); + assertEval("class Test3 { T[][] get() { return null; } }", added(VALID)); + assertEval("Test3 test3 = new Test3<>();"); + VarSnippet sn6 = (VarSnippet) varKey(assertEval("test3.get()")); + assertEquals(sn6.typeName(), "String[][]"); } } diff -r 4edcff1b9a88 -r 36d62753f5da langtools/test/jdk/jshell/VariablesTest.java --- a/langtools/test/jdk/jshell/VariablesTest.java Wed Jul 05 21:07:43 2017 +0200 +++ b/langtools/test/jdk/jshell/VariablesTest.java Fri Dec 11 11:20:10 2015 -0800 @@ -23,6 +23,7 @@ /* * @test + * @bug 8144903 * @summary Tests for EvaluationState.variables * @build KullaTesting TestingInputStream ExpectedDiagnostic * @run testng VariablesTest @@ -184,6 +185,16 @@ 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<>();", "[]",