ClassesTest.java revision 3731:6bb6785c2329
1/* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * @test 26 * @bug 8145239 27 * @summary Tests for EvaluationState.classes 28 * @build KullaTesting TestingInputStream ExpectedDiagnostic 29 * @run testng ClassesTest 30 */ 31 32import java.util.ArrayList; 33import java.util.List; 34 35import javax.tools.Diagnostic; 36 37import jdk.jshell.Snippet; 38import jdk.jshell.TypeDeclSnippet; 39import jdk.jshell.VarSnippet; 40import org.testng.annotations.DataProvider; 41import org.testng.annotations.Test; 42 43import jdk.jshell.Diag; 44import static java.util.stream.Collectors.toList; 45import static jdk.jshell.Snippet.Status.VALID; 46import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED; 47import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED; 48import static jdk.jshell.Snippet.Status.DROPPED; 49import static jdk.jshell.Snippet.Status.REJECTED; 50import static jdk.jshell.Snippet.Status.OVERWRITTEN; 51import static jdk.jshell.Snippet.Status.NONEXISTENT; 52import static jdk.jshell.Snippet.SubKind.*; 53import static org.testng.Assert.assertEquals; 54import static org.testng.Assert.assertTrue; 55 56@Test 57public class ClassesTest extends KullaTesting { 58 59 public void noClasses() { 60 assertNumberOfActiveClasses(0); 61 } 62 63 public void testSignature1() { 64 TypeDeclSnippet c1 = classKey(assertEval("class A extends B {}", added(RECOVERABLE_NOT_DEFINED))); 65 assertTypeDeclSnippet(c1, "A", RECOVERABLE_NOT_DEFINED, CLASS_SUBKIND, 1, 0); 66 TypeDeclSnippet c2 = classKey(assertEval("@interface A { Class<B> f() default B.class; }", 67 ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null), 68 ste(c1, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET))); 69 assertTypeDeclSnippet(c2, "A", RECOVERABLE_NOT_DEFINED, ANNOTATION_TYPE_SUBKIND, 1, 0); 70 TypeDeclSnippet c3 = classKey(assertEval("enum A {; private A(B b) {} }", 71 ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null), 72 ste(c2, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET))); 73 assertTypeDeclSnippet(c3, "A", RECOVERABLE_NOT_DEFINED, ENUM_SUBKIND, 1, 0); 74 TypeDeclSnippet c4 = classKey(assertEval("interface A extends B {}", 75 ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null), 76 ste(c3, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET))); 77 assertTypeDeclSnippet(c4, "A", RECOVERABLE_NOT_DEFINED, INTERFACE_SUBKIND, 1, 0); 78 TypeDeclSnippet c5 = classKey(assertEval("class A { void f(B b) {} }", 79 ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null), 80 ste(c4, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET))); 81 assertTypeDeclSnippet(c5, "A", RECOVERABLE_NOT_DEFINED, CLASS_SUBKIND, 1, 0); 82 } 83 84 public void testSignature2() { 85 TypeDeclSnippet c1 = (TypeDeclSnippet) assertDeclareFail("class A { void f() { return g(); } }", "compiler.err.prob.found.req"); 86 assertTypeDeclSnippet(c1, "A", REJECTED, CLASS_SUBKIND, 0, 2); 87 TypeDeclSnippet c2 = classKey(assertEval("class A { int f() { return g(); } }", 88 ste(c1, NONEXISTENT, RECOVERABLE_DEFINED, true, null))); 89 assertTypeDeclSnippet(c2, "A", RECOVERABLE_DEFINED, CLASS_SUBKIND, 1, 0); 90 assertDrop(c2, 91 ste(c2, RECOVERABLE_DEFINED, DROPPED, true, null)); 92 } 93 94 public void classDeclaration() { 95 assertEval("class A { }"); 96 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A")); 97 } 98 99 100 public void interfaceDeclaration() { 101 assertEval("interface A { }"); 102 assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A")); 103 } 104 105 public void annotationDeclaration() { 106 assertEval("@interface A { }"); 107 assertClasses(clazz(KullaTesting.ClassType.ANNOTATION, "A")); 108 } 109 110 public void enumDeclaration() { 111 assertEval("enum A { }"); 112 assertClasses(clazz(KullaTesting.ClassType.ENUM, "A")); 113 } 114 115 public void classesDeclaration() { 116 assertEval("interface A { }"); 117 assertEval("class B implements A { }"); 118 assertEval("interface C extends A { }"); 119 assertEval("enum D implements C { }"); 120 assertEval("@interface E { }"); 121 assertClasses( 122 clazz(KullaTesting.ClassType.INTERFACE, "A"), 123 clazz(KullaTesting.ClassType.CLASS, "B"), 124 clazz(KullaTesting.ClassType.INTERFACE, "C"), 125 clazz(KullaTesting.ClassType.ENUM, "D"), 126 clazz(KullaTesting.ClassType.ANNOTATION, "E")); 127 assertActiveKeys(); 128 } 129 130 public void classesRedeclaration1() { 131 Snippet a = classKey(assertEval("class A { }")); 132 Snippet b = classKey(assertEval("interface B { }")); 133 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"), clazz(KullaTesting.ClassType.INTERFACE, "B")); 134 assertActiveKeys(); 135 136 assertEval("interface A { }", 137 ste(MAIN_SNIPPET, VALID, VALID, true, null), 138 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 139 assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"), 140 clazz(KullaTesting.ClassType.INTERFACE, "B")); 141 assertActiveKeys(); 142 143 assertEval("interface B { } //again", 144 ste(MAIN_SNIPPET, VALID, VALID, false, null), 145 ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 146 assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"), 147 clazz(KullaTesting.ClassType.INTERFACE, "B")); 148 assertActiveKeys(); 149 } 150 151 public void classesRedeclaration2() { 152 assertEval("class A { }"); 153 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A")); 154 assertActiveKeys(); 155 156 Snippet b = classKey(assertEval("class B extends A { }")); 157 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"), 158 clazz(KullaTesting.ClassType.CLASS, "B")); 159 assertActiveKeys(); 160 161 Snippet c = classKey(assertEval("class C extends B { }")); 162 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"), 163 clazz(KullaTesting.ClassType.CLASS, "B"), clazz(KullaTesting.ClassType.CLASS, "C")); 164 assertActiveKeys(); 165 166 assertEval("interface B { }", 167 DiagCheck.DIAG_OK, 168 DiagCheck.DIAG_ERROR, 169 ste(MAIN_SNIPPET, VALID, VALID, true, null), 170 ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 171 ste(c, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET)); 172 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"), 173 clazz(KullaTesting.ClassType.INTERFACE, "B"), clazz(KullaTesting.ClassType.CLASS, "C")); 174 assertEval("new C();", 175 DiagCheck.DIAG_ERROR, 176 DiagCheck.DIAG_ERROR, 177 added(REJECTED)); 178 assertActiveKeys(); 179 } 180 181 //8154496: test3 update: sig change should false 182 public void classesRedeclaration3() { 183 Snippet a = classKey(assertEval("class A { }")); 184 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A")); 185 assertActiveKeys(); 186 187 Snippet test1 = methodKey(assertEval("A test() { return null; }")); 188 Snippet test2 = methodKey(assertEval("void test(A a) { }")); 189 Snippet test3 = methodKey(assertEval("void test(int n) {A a;}")); 190 assertActiveKeys(); 191 192 assertEval("interface A { }", 193 ste(MAIN_SNIPPET, VALID, VALID, true, null), 194 ste(test1, VALID, VALID, true, MAIN_SNIPPET), 195 ste(test2, VALID, VALID, true, MAIN_SNIPPET), 196 ste(test3, VALID, VALID, true, MAIN_SNIPPET), 197 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 198 assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A")); 199 assertMethods(method("()A", "test"), method("(A)void", "test"), method("(int)void", "test")); 200 assertActiveKeys(); 201 } 202 203 public void classesCyclic1() { 204 Snippet b = classKey(assertEval("class B extends A { }", 205 added(RECOVERABLE_NOT_DEFINED))); 206 Snippet a = classKey(assertEval("class A extends B { }", DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE, 207 added(REJECTED))); 208 /*** 209 assertDeclareFail("class A extends B { }", "****", 210 added(REJECTED), 211 ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET)); 212 ***/ 213 // It is random which one it shows up in, but cyclic error should be there 214 List<Diag> diagsA = getState().diagnostics(a).collect(toList()); 215 List<Diag> diagsB = getState().diagnostics(b).collect(toList()); 216 List<Diag> diags; 217 if (diagsA.isEmpty()) { 218 diags = diagsB; 219 } else { 220 diags = diagsA; 221 assertTrue(diagsB.isEmpty()); 222 } 223 assertEquals(diags.size(), 1, "Expected one error"); 224 assertEquals(diags.get(0).getCode(), "compiler.err.cyclic.inheritance", "Expected cyclic inheritance error"); 225 assertActiveKeys(); 226 } 227 228 public void classesCyclic2() { 229 Snippet d = classKey(assertEval("class D extends E { }", added(RECOVERABLE_NOT_DEFINED))); 230 assertEval("class E { D d; }", 231 added(VALID), 232 ste(d, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET)); 233 assertActiveKeys(); 234 } 235 236 public void classesCyclic3() { 237 Snippet outer = classKey(assertEval("class Outer { class Inner extends Foo { } }", 238 added(RECOVERABLE_NOT_DEFINED))); 239 Snippet foo = classKey(assertEval("class Foo { } ", 240 added(VALID), 241 ste(outer, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET))); 242 assertEval(" class Foo extends Outer { }", 243 ste(MAIN_SNIPPET, VALID, VALID, true, null), 244 ste(foo, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 245 ste(outer, VALID, VALID, true, MAIN_SNIPPET)); 246 assertActiveKeys(); 247 } 248 249 public void classesIgnoredModifiers() { 250 assertEval("public interface A { }"); 251 assertDeclareWarn1("static class B implements A { }", 252 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING)); 253 assertDeclareWarn1("final interface C extends A { }", 254 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 5, 0, -1, -1, Diagnostic.Kind.WARNING)); 255 assertActiveKeys(); 256 } 257 258 public void ignoreModifierSpaceIssue() { 259 assertEval("interface I { void f(); } "); 260 // there should not be a space between 'I' and '{' to reproduce the failure 261 assertEval("class C implements I{ public void f() {}}"); 262 assertClasses(clazz(KullaTesting.ClassType.CLASS, "C"), clazz(KullaTesting.ClassType.INTERFACE, "I")); 263 assertActiveKeys(); 264 } 265 266 @DataProvider(name = "innerClasses") 267 public Object[][] innerClasses() { 268 List<Object[]> list = new ArrayList<>(); 269 for (ClassType outerClassType : ClassType.values()) { 270 for (ClassType innerClassType : ClassType.values()) { 271 list.add(new Object[]{outerClassType, innerClassType}); 272 } 273 } 274 return list.toArray(new Object[list.size()][]); 275 } 276 277 @Test(dataProvider = "innerClasses") 278 public void innerClasses(ClassType outerClassType, ClassType innerClassType) { 279 String source = 280 outerClassType + " A {" + (outerClassType == ClassType.ENUM ? ";" : "") + 281 innerClassType + " B { }" + 282 "}"; 283 assertEval(source); 284 assertNumberOfActiveClasses(1); 285 assertActiveKeys(); 286 } 287 288 public void testInnerClassesCrash() { 289 Snippet a = classKey(assertEval("class A { class B extends A {} }")); 290 Snippet a2 = classKey(assertEval("class A { interface I1 extends I2 {} interface I2 {} }", 291 ste(MAIN_SNIPPET, VALID, VALID, false, null), 292 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET))); 293 assertEval("class A { A a = new A() {}; }", 294 ste(MAIN_SNIPPET, VALID, VALID, true, null), 295 ste(a2, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 296 } 297 298 public void testInnerClassesCrash1() { 299 assertEval("class A { class B extends A {} B getB() { return new B();} }"); 300 assertEquals(varKey(assertEval("A a = new A();")).name(), "a"); 301 VarSnippet variableKey = varKey(assertEval("a.getB();")); 302 assertEquals(variableKey.typeName(), "A.B"); 303 } 304 305 public void testInnerClassesCrash2() { 306 assertEval("class A { interface I1 extends I2 {} interface I2 {} I1 x; }"); 307 assertEquals(varKey(assertEval("A a = new A();")).name(), "a"); 308 VarSnippet variableKey = varKey(assertEval("a.x;")); 309 assertEquals(variableKey.typeName(), "A.I1"); 310 } 311} 312