ClassesTest.java revision 3062:15bdc18525ff
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 * @summary Tests for EvaluationState.classes 27 * @build KullaTesting TestingInputStream ExpectedDiagnostic 28 * @run testng ClassesTest 29 */ 30 31import java.util.ArrayList; 32import java.util.List; 33 34import javax.tools.Diagnostic; 35 36import jdk.jshell.Snippet; 37import jdk.jshell.TypeDeclSnippet; 38import jdk.jshell.VarSnippet; 39import org.testng.annotations.DataProvider; 40import org.testng.annotations.Test; 41 42import jdk.jshell.Diag; 43import static jdk.jshell.Snippet.Status.VALID; 44import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED; 45import static jdk.jshell.Snippet.Status.DROPPED; 46import static jdk.jshell.Snippet.Status.REJECTED; 47import static jdk.jshell.Snippet.SubKind.*; 48import static org.testng.Assert.assertEquals; 49import static org.testng.Assert.assertTrue; 50import static jdk.jshell.Snippet.Status.OVERWRITTEN; 51 52@Test 53public class ClassesTest extends KullaTesting { 54 55 public void noClasses() { 56 assertNumberOfActiveClasses(0); 57 } 58 59 public void testSignature1() { 60 TypeDeclSnippet c1 = classKey(assertEval("class A extends B {}", added(RECOVERABLE_NOT_DEFINED))); 61 assertTypeDeclSnippet(c1, "A", RECOVERABLE_NOT_DEFINED, CLASS_SUBKIND, 1, 0); 62 TypeDeclSnippet c2 = classKey(assertEval("@interface A { Class<B> f() default B.class; }", 63 ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null), 64 ste(c1, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET))); 65 assertTypeDeclSnippet(c2, "A", RECOVERABLE_NOT_DEFINED, ANNOTATION_TYPE_SUBKIND, 1, 0); 66 TypeDeclSnippet c3 = classKey(assertEval("enum A {; private A(B b) {} }", 67 ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null), 68 ste(c2, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET))); 69 assertTypeDeclSnippet(c3, "A", RECOVERABLE_NOT_DEFINED, ENUM_SUBKIND, 1, 0); 70 TypeDeclSnippet c4 = classKey(assertEval("interface A extends B {}", 71 ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null), 72 ste(c3, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET))); 73 assertTypeDeclSnippet(c4, "A", RECOVERABLE_NOT_DEFINED, INTERFACE_SUBKIND, 1, 0); 74 TypeDeclSnippet c5 = classKey(assertEval("class A { void f(B b) {} }", 75 ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null), 76 ste(c4, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET))); 77 assertTypeDeclSnippet(c5, "A", RECOVERABLE_NOT_DEFINED, CLASS_SUBKIND, 1, 0); 78 } 79 80 public void testSignature2() { 81 TypeDeclSnippet c1 = (TypeDeclSnippet) assertDeclareFail("class A { void f() { return g(); } }", "compiler.err.prob.found.req"); 82 assertTypeDeclSnippet(c1, "A", REJECTED, CLASS_SUBKIND, 0, 2); 83 TypeDeclSnippet c2 = classKey(assertEval("class A { int f() { return g(); } }", 84 ste(c1, REJECTED, RECOVERABLE_NOT_DEFINED, false, null))); 85 assertTypeDeclSnippet(c2, "A", RECOVERABLE_NOT_DEFINED, CLASS_SUBKIND, 1, 0); 86 assertDrop(c2, 87 ste(c2, RECOVERABLE_NOT_DEFINED, DROPPED, false, null)); 88 } 89 90 public void classDeclaration() { 91 assertEval("class A { }"); 92 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A")); 93 } 94 95 96 public void interfaceDeclaration() { 97 assertEval("interface A { }"); 98 assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A")); 99 } 100 101 public void annotationDeclaration() { 102 assertEval("@interface A { }"); 103 assertClasses(clazz(KullaTesting.ClassType.ANNOTATION, "A")); 104 } 105 106 public void enumDeclaration() { 107 assertEval("enum A { }"); 108 assertClasses(clazz(KullaTesting.ClassType.ENUM, "A")); 109 } 110 111 public void classesDeclaration() { 112 assertEval("interface A { }"); 113 assertEval("class B implements A { }"); 114 assertEval("interface C extends A { }"); 115 assertEval("enum D implements C { }"); 116 assertEval("@interface E { }"); 117 assertClasses( 118 clazz(KullaTesting.ClassType.INTERFACE, "A"), 119 clazz(KullaTesting.ClassType.CLASS, "B"), 120 clazz(KullaTesting.ClassType.INTERFACE, "C"), 121 clazz(KullaTesting.ClassType.ENUM, "D"), 122 clazz(KullaTesting.ClassType.ANNOTATION, "E")); 123 assertActiveKeys(); 124 } 125 126 public void classesRedeclaration1() { 127 Snippet a = classKey(assertEval("class A { }")); 128 Snippet b = classKey(assertEval("interface B { }")); 129 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"), clazz(KullaTesting.ClassType.INTERFACE, "B")); 130 assertActiveKeys(); 131 132 assertEval("interface A { }", 133 ste(MAIN_SNIPPET, VALID, VALID, true, null), 134 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 135 assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"), 136 clazz(KullaTesting.ClassType.INTERFACE, "B")); 137 assertActiveKeys(); 138 139 assertEval("interface B { } //again", 140 ste(MAIN_SNIPPET, VALID, VALID, false, null), 141 ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 142 assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"), 143 clazz(KullaTesting.ClassType.INTERFACE, "B")); 144 assertActiveKeys(); 145 } 146 147 public void classesRedeclaration2() { 148 assertEval("class A { }"); 149 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A")); 150 assertActiveKeys(); 151 152 Snippet b = classKey(assertEval("class B extends A { }")); 153 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"), 154 clazz(KullaTesting.ClassType.CLASS, "B")); 155 assertActiveKeys(); 156 157 Snippet c = classKey(assertEval("class C extends B { }")); 158 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"), 159 clazz(KullaTesting.ClassType.CLASS, "B"), clazz(KullaTesting.ClassType.CLASS, "C")); 160 assertActiveKeys(); 161 162 assertEval("interface B { }", 163 DiagCheck.DIAG_OK, 164 DiagCheck.DIAG_ERROR, 165 ste(MAIN_SNIPPET, VALID, VALID, true, null), 166 ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 167 ste(c, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET)); 168 assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"), 169 clazz(KullaTesting.ClassType.INTERFACE, "B"), clazz(KullaTesting.ClassType.CLASS, "C")); 170 assertEval("new C();", 171 DiagCheck.DIAG_ERROR, 172 DiagCheck.DIAG_ERROR, 173 added(REJECTED)); 174 assertActiveKeys(); 175 } 176 177 public void classesCyclic1() { 178 Snippet b = classKey(assertEval("class B extends A { }", 179 added(RECOVERABLE_NOT_DEFINED))); 180 Snippet a = classKey(assertEval("class A extends B { }", DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE, 181 added(RECOVERABLE_NOT_DEFINED), 182 ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET))); 183 /*** 184 assertDeclareFail("class A extends B { }", "****", 185 added(REJECTED), 186 ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET)); 187 ***/ 188 // It is random which one it shows up in, but cyclic error should be there 189 List<Diag> diagsA = getState().diagnostics(a); 190 List<Diag> diagsB = getState().diagnostics(b); 191 List<Diag> diags; 192 if (diagsA.isEmpty()) { 193 diags = diagsB; 194 } else { 195 diags = diagsA; 196 assertTrue(diagsB.isEmpty()); 197 } 198 assertEquals(diags.size(), 1, "Expected one error"); 199 assertEquals(diags.get(0).getCode(), "compiler.err.cyclic.inheritance", "Expected cyclic inheritance error"); 200 assertActiveKeys(); 201 } 202 203 public void classesCyclic2() { 204 Snippet d = classKey(assertEval("class D extends E { }", added(RECOVERABLE_NOT_DEFINED))); 205 assertEval("class E { D d; }", 206 added(VALID), 207 ste(d, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET)); 208 assertActiveKeys(); 209 } 210 211 public void classesCyclic3() { 212 Snippet outer = classKey(assertEval("class Outer { class Inner extends Foo { } }", 213 added(RECOVERABLE_NOT_DEFINED))); 214 Snippet foo = classKey(assertEval("class Foo { } ", 215 added(VALID), 216 ste(outer, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET))); 217 assertEval(" class Foo extends Outer { }", 218 ste(MAIN_SNIPPET, VALID, VALID, true, null), 219 ste(foo, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 220 ste(outer, VALID, VALID, true, MAIN_SNIPPET)); 221 assertActiveKeys(); 222 } 223 224 public void classesIgnoredModifiers() { 225 assertDeclareWarn1("public interface A { }", 226 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING)); 227 assertDeclareWarn1("static class B implements A { }", 228 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING)); 229 assertDeclareWarn1("final interface C extends A { }", 230 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 5, 0, -1, -1, Diagnostic.Kind.WARNING)); 231 assertDeclareWarn1("protected enum D implements C { }", 232 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 9, 0, -1, -1, Diagnostic.Kind.WARNING)); 233 assertActiveKeys(); 234 } 235 236 public void ignoreModifierSpaceIssue() { 237 assertEval("interface I { void f(); } "); 238 // there should not be a space between 'I' and '{' to reproduce the failure 239 assertEval("class C implements I{ public void f() {}}"); 240 assertClasses(clazz(KullaTesting.ClassType.CLASS, "C"), clazz(KullaTesting.ClassType.INTERFACE, "I")); 241 assertActiveKeys(); 242 } 243 244 @DataProvider(name = "innerClasses") 245 public Object[][] innerClasses() { 246 List<Object[]> list = new ArrayList<>(); 247 for (ClassType outerClassType : ClassType.values()) { 248 for (ClassType innerClassType : ClassType.values()) { 249 list.add(new Object[]{outerClassType, innerClassType}); 250 } 251 } 252 return list.toArray(new Object[list.size()][]); 253 } 254 255 @Test(dataProvider = "innerClasses") 256 public void innerClasses(ClassType outerClassType, ClassType innerClassType) { 257 String source = 258 outerClassType + " A {" + (outerClassType == ClassType.ENUM ? ";" : "") + 259 innerClassType + " B { }" + 260 "}"; 261 assertEval(source); 262 assertNumberOfActiveClasses(1); 263 assertActiveKeys(); 264 } 265 266 public void testInnerClassesCrash() { 267 Snippet a = classKey(assertEval("class A { class B extends A {} }")); 268 Snippet a2 = classKey(assertEval("class A { interface I1 extends I2 {} interface I2 {} }", 269 ste(MAIN_SNIPPET, VALID, VALID, false, null), 270 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET))); 271 assertEval("class A { A a = new A() {}; }", 272 ste(MAIN_SNIPPET, VALID, VALID, true, null), 273 ste(a2, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 274 } 275 276 public void testInnerClassesCrash1() { 277 assertEval("class A { class B extends A {} B getB() { return new B();} }"); 278 assertEquals(varKey(assertEval("A a = new A();")).name(), "a"); 279 VarSnippet variableKey = varKey(assertEval("a.getB();")); 280 assertEquals(variableKey.typeName(), "A.B"); 281 } 282 283 public void testInnerClassesCrash2() { 284 assertEval("class A { interface I1 extends I2 {} interface I2 {} I1 x; }"); 285 assertEquals(varKey(assertEval("A a = new A();")).name(), "a"); 286 VarSnippet variableKey = varKey(assertEval("a.x;")); 287 assertEquals(variableKey.typeName(), "A.I1"); 288 } 289} 290