ReplaceTest.java revision 3357:3e3553ee39d9
1/* 2 * Copyright (c) 2015, 2016, 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 8080069 8152925 26 * @summary Test of Snippet redefinition and replacement. 27 * @build KullaTesting TestingInputStream 28 * @run testng ReplaceTest 29 */ 30 31import java.util.Collection; 32 33import java.util.List; 34import jdk.jshell.Snippet; 35import jdk.jshell.MethodSnippet; 36import jdk.jshell.PersistentSnippet; 37import jdk.jshell.TypeDeclSnippet; 38import jdk.jshell.VarSnippet; 39import jdk.jshell.DeclarationSnippet; 40import org.testng.annotations.Test; 41 42import jdk.jshell.SnippetEvent; 43import jdk.jshell.UnresolvedReferenceException; 44import static org.testng.Assert.assertEquals; 45import static jdk.jshell.Snippet.Status.*; 46import static jdk.jshell.Snippet.SubKind.*; 47import static org.testng.Assert.assertTrue; 48 49@Test 50public class ReplaceTest extends KullaTesting { 51 52 public void testRedefine() { 53 Snippet vx = varKey(assertEval("int x;")); 54 Snippet mu = methodKey(assertEval("int mu() { return x * 4; }")); 55 Snippet c = classKey(assertEval("class C { String v() { return \"#\" + mu(); } }")); 56 assertEval("C c0 = new C();"); 57 assertEval("c0.v();", "\"#0\""); 58 assertEval("int x = 10;", "10", 59 ste(MAIN_SNIPPET, VALID, VALID, false, null), 60 ste(vx, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 61 assertEval("c0.v();", "\"#40\""); 62 assertEval("C c = new C();"); 63 assertEval("c.v();", "\"#40\""); 64 assertEval("int mu() { return x * 3; }", 65 ste(MAIN_SNIPPET, VALID, VALID, false, null), 66 ste(mu, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 67 assertEval("c.v();", "\"#30\""); 68 assertEval("class C { String v() { return \"@\" + mu(); } }", 69 ste(MAIN_SNIPPET, VALID, VALID, false, null), 70 ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 71 assertEval("c0.v();", "\"@30\""); 72 assertEval("c = new C();"); 73 assertEval("c.v();", "\"@30\""); 74 assertActiveKeys(); 75 } 76 77 public void testReplaceClassToVar() { 78 Snippet oldA = classKey(assertEval("class A { public String toString() { return \"old\"; } }")); 79 Snippet v = varKey(assertEval("A a = new A();", "old")); 80 assertEval("a;", "old"); 81 Snippet midA = classKey(assertEval("class A { public String toString() { return \"middle\"; } }", 82 ste(MAIN_SNIPPET, VALID, VALID, false, null), 83 ste(oldA, VALID, OVERWRITTEN, false, MAIN_SNIPPET))); 84 assertEval("a;", "middle"); 85 assertEval("class A { int x; public String toString() { return \"new\"; } }", 86 ste(MAIN_SNIPPET, VALID, VALID, true, null), 87 ste(midA, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 88 ste(v, VALID, VALID, true, MAIN_SNIPPET)); 89 assertEval("a;", "null"); 90 assertActiveKeys(); 91 } 92 93 public void testReplaceVarToMethod() { 94 Snippet x = varKey(assertEval("int x;")); 95 Snippet musn = methodKey(assertEval("double mu() { return x * 4; }")); 96 assertEval("x == 0;", "true"); 97 assertEval("mu() == 0.0;", "true"); 98 assertEval("double x = 2.5;", 99 ste(MAIN_SNIPPET, VALID, VALID, true, null), 100 ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 101 Collection<MethodSnippet> meths = getState().methods(); 102 assertEquals(meths.size(), 1); 103 assertTrue(musn == meths.iterator().next(), "Identity must not change"); 104 assertEval("x == 2.5;", "true"); 105 assertEval("mu() == 10.0;", "true"); // Auto redefine 106 assertActiveKeys(); 107 } 108 109 public void testReplaceMethodToMethod() { 110 Snippet a = methodKey(assertEval("double a() { return 2; }")); 111 Snippet b = methodKey(assertEval("double b() { return a() * 10; }")); 112 assertEval("double c() { return b() * 3; }"); 113 assertEval("double d() { return c() + 1000; }"); 114 assertEval("d();", "1060.0"); 115 assertEval("int a() { return 5; }", 116 ste(MAIN_SNIPPET, VALID, VALID, true, null), 117 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 118 assertEval("d();", "1150.0"); 119 assertActiveKeys(); 120 } 121 122 public void testReplaceClassToMethod() { 123 Snippet c = classKey(assertEval("class C { int f() { return 7; } }")); 124 Snippet m = methodKey(assertEval("int m() { return new C().f(); }")); 125 assertEval("m();", "7"); 126 assertEval("class C { int x = 99; int f() { return x; } }", 127 ste(MAIN_SNIPPET, VALID, VALID, true, null), 128 ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 129 assertEval("m();", "99"); 130 assertActiveKeys(); 131 } 132 133 public void testReplaceVarToClass() { 134 Snippet x = varKey(assertEval("int x;")); 135 Snippet c = classKey(assertEval("class A { double a = 4 * x; }")); 136 assertEval("x == 0;", "true"); 137 assertEval("new A().a == 0.0;", "true"); 138 assertEval("double x = 2.5;", 139 ste(MAIN_SNIPPET, VALID, VALID, true, null), 140 ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 141 Collection<TypeDeclSnippet> classes = getState().types(); 142 assertEquals(classes.size(), 1); 143 assertTrue(c == classes.iterator().next(), "Identity must not change"); 144 assertEval("x == 2.5;", "true"); 145 assertEval("new A().a == 10.0;", "true"); 146 assertActiveKeys(); 147 } 148 149 public void testReplaceMethodToClass() { 150 Snippet x = methodKey(assertEval("int x() { return 0; }")); 151 Snippet c = classKey(assertEval("class A { double a = 4 * x(); }")); 152 assertEval("x() == 0;", "true"); 153 assertEval("new A().a == 0.0;", "true"); 154 assertEval("double x() { return 2.5; }", 155 ste(MAIN_SNIPPET, VALID, VALID, true, null), 156 ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 157 assertEval("x();", "2.5"); 158 Collection<TypeDeclSnippet> classes = getState().types(); 159 assertEquals(classes.size(), 1); 160 assertTrue(c == classes.iterator().next(), "Identity must not change"); 161 assertEval("x() == 2.5;", "true"); 162 assertEval("new A().a == 10.0;", "true"); 163 assertActiveKeys(); 164 } 165 166 public void testReplaceClassToClass() { 167 TypeDeclSnippet a = classKey(assertEval("class A {}")); 168 assertTypeDeclSnippet(a, "A", VALID, CLASS_SUBKIND, 0, 0); 169 TypeDeclSnippet b = classKey(assertEval("class B extends A {}")); 170 TypeDeclSnippet c = classKey(assertEval("class C extends B {}")); 171 TypeDeclSnippet d = classKey(assertEval("class D extends C {}")); 172 assertEval("class A { int x; public String toString() { return \"NEW\"; } }", 173 ste(MAIN_SNIPPET, VALID, VALID, true, null), 174 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 175 ste(b, VALID, VALID, true, MAIN_SNIPPET), 176 ste(c, VALID, VALID, true, b), 177 ste(d, VALID, VALID, true, c)); 178 assertTypeDeclSnippet(b, "B", VALID, CLASS_SUBKIND, 0, 0); 179 assertTypeDeclSnippet(c, "C", VALID, CLASS_SUBKIND, 0, 0); 180 assertTypeDeclSnippet(d, "D", VALID, CLASS_SUBKIND, 0, 0); 181 assertEval("new D();", "NEW"); 182 assertActiveKeys(); 183 } 184 185 public void testOverwriteReplaceMethod() { 186 MethodSnippet k1 = methodKey(assertEval("String m(Integer i) { return i.toString(); }")); 187 MethodSnippet k2 = methodKey(assertEval("String m(java.lang.Integer i) { return \"java.lang.\" + i.toString(); }", 188 ste(MAIN_SNIPPET, VALID, VALID, true, null), 189 ste(k1, VALID, OVERWRITTEN, false, MAIN_SNIPPET))); 190 assertMethodDeclSnippet(k1, "m", "(Integer)String", OVERWRITTEN, 0, 0); 191 assertEval("m(6);", "\"java.lang.6\""); 192 assertEval("String m(Integer i) { return i.toString(); }", 193 ste(MAIN_SNIPPET, VALID, VALID, true, null), 194 ste(k2, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 195 assertMethodDeclSnippet(k2, "m", "(java.lang.Integer)String", OVERWRITTEN, 0, 0); 196 assertEval("m(6);", "\"6\""); 197 assertActiveKeys(); 198 } 199 200 public void testOverwriteMethodForwardReferenceClass() { 201 Snippet k1 = methodKey(assertEval("int q(Boo b) { return b.x; }", 202 added(RECOVERABLE_NOT_DEFINED))); 203 assertUnresolvedDependencies1((MethodSnippet) k1, RECOVERABLE_NOT_DEFINED, "class Boo"); 204 assertEval("class Boo { int x = 55; }", 205 added(VALID), 206 ste(k1, RECOVERABLE_NOT_DEFINED, VALID, true, null)); 207 assertMethodDeclSnippet((MethodSnippet) k1, "q", "(Boo)int", VALID, 0, 0); 208 assertEval("q(new Boo());", "55"); 209 assertActiveKeys(); 210 } 211 212 public void testOverwriteMethodForwardReferenceClassImport() { 213 MethodSnippet k1 = methodKey(assertEval("int ff(List lis) { return lis.size(); }", 214 added(RECOVERABLE_NOT_DEFINED))); 215 assertUnresolvedDependencies1(k1, RECOVERABLE_NOT_DEFINED, "class List"); 216 assertEval("import java.util.*;", 217 added(VALID), 218 ste(k1, RECOVERABLE_NOT_DEFINED, VALID, true, null)); 219 assertMethodDeclSnippet(k1, "ff", "(List)int", VALID, 0, 0); 220 assertEval("ff(new ArrayList());", "0"); 221 assertActiveKeys(); 222 } 223 224 public void testForwardVarToMethod() { 225 DeclarationSnippet t = methodKey(assertEval("int t() { return x; }", added(RECOVERABLE_DEFINED))); 226 assertUnresolvedDependencies1(t, RECOVERABLE_DEFINED, "variable x"); 227 assertEvalUnresolvedException("t();", "t", 1, 0); 228 Snippet x = varKey(assertEval("int x = 33;", "33", 229 added(VALID), 230 ste(t, RECOVERABLE_DEFINED, VALID, false, null))); 231 assertEval("t();", "33"); 232 assertEval("double x = 0.88;", 233 "0.88", null, 234 DiagCheck.DIAG_OK, 235 DiagCheck.DIAG_ERROR, 236 ste(MAIN_SNIPPET, VALID, VALID, true, null), 237 ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 238 ste(t, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET)); 239 assertEvalUnresolvedException("t();", "t", 0, 1); 240 assertActiveKeys(); 241 } 242 243 public void testForwardMethodToMethod() { 244 Snippet t = methodKey(assertEval("int t() { return f(); }", added(RECOVERABLE_DEFINED))); 245 Snippet f = methodKey(assertEval("int f() { return g(); }", 246 added(RECOVERABLE_DEFINED), 247 ste(t, RECOVERABLE_DEFINED, VALID, false, null))); 248 assertUnresolvedDependencies1((DeclarationSnippet) f, RECOVERABLE_DEFINED, "method g()"); 249 assertEvalUnresolvedException("t();", "f", 1, 0); 250 Snippet g = methodKey(assertEval("int g() { return 55; }", 251 added(VALID), 252 ste(f, RECOVERABLE_DEFINED, VALID, false, null))); 253 assertEval("t();", "55"); 254 assertEval("double g() { return 3.14159; }", 255 DiagCheck.DIAG_OK, 256 DiagCheck.DIAG_ERROR, 257 ste(MAIN_SNIPPET, VALID, VALID, true, null), 258 ste(g, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 259 ste(f, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET)); 260 DeclarationSnippet exsn = assertEvalUnresolvedException("t();", "f", 0, 1); 261 assertTrue(exsn == f, "Identity must not change"); 262 assertActiveKeys(); 263 } 264 265 public void testForwardClassToMethod() { 266 DeclarationSnippet t = methodKey(assertEval("int t() { return new A().f(); }", added(RECOVERABLE_DEFINED))); 267 assertUnresolvedDependencies1(t, RECOVERABLE_DEFINED, "class A"); 268 assertEvalUnresolvedException("t();", "t", 1, 0); 269 Snippet a = classKey(assertEval( 270 "class A {\n" + 271 " int f() { return 10; }\n" + 272 "}", 273 added(VALID), 274 ste(t, RECOVERABLE_DEFINED, VALID, false, null))); 275 assertEval("t();", "10"); 276 assertEval( 277 "class A {\n" + 278 " double f() { return 88.0; }\n" + 279 "}", 280 DiagCheck.DIAG_OK, 281 DiagCheck.DIAG_ERROR, 282 ste(MAIN_SNIPPET, VALID, VALID, true, null), 283 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 284 ste(t, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET)); 285 assertEvalUnresolvedException("t();", "t", 0, 1); 286 assertActiveKeys(); 287 } 288 289 public void testForwardVarToClass() { 290 DeclarationSnippet a = classKey(assertEval("class A { int f() { return g; } }", added(RECOVERABLE_DEFINED))); 291 assertUnresolvedDependencies1(a, RECOVERABLE_DEFINED, "variable g"); 292 Snippet g = varKey(assertEval("int g = 10;", "10", 293 added(VALID), 294 ste(a, RECOVERABLE_DEFINED, VALID, false, null))); 295 assertEval("new A().f();", "10"); 296 assertEval("double g = 10;", "10.0", null, 297 DiagCheck.DIAG_OK, 298 DiagCheck.DIAG_ERROR, 299 ste(MAIN_SNIPPET, VALID, VALID, true, null), 300 ste(g, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 301 ste(a, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET)); 302 assertUnresolvedDependencies(a, 0); 303 assertActiveKeys(); 304 } 305 306 public void testForwardVarToClassGeneric() { 307 DeclarationSnippet a = classKey(assertEval("class A<T> { final T x; A(T v) { this.x = v; } ; T get() { return x; } int core() { return g; } }", added(RECOVERABLE_DEFINED))); 308 assertUnresolvedDependencies1(a, RECOVERABLE_DEFINED, "variable g"); 309 310 List<SnippetEvent> events = assertEval("A<String> as = new A<>(\"hi\");", null, 311 UnresolvedReferenceException.class, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, null); 312 SnippetEvent ste = events.get(0); 313 Snippet assn = ste.snippet(); 314 DeclarationSnippet unsn = ((UnresolvedReferenceException) ste.exception()).getSnippet(); 315 assertEquals(unsn.name(), "A", "Wrong with unresolved"); 316 assertEquals(getState().unresolvedDependencies(unsn).size(), 1, "Wrong size unresolved"); 317 assertEquals(getState().diagnostics(unsn).size(), 0, "Expected no diagnostics"); 318 319 Snippet g = varKey(assertEval("int g = 10;", "10", 320 added(VALID), 321 ste(a, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET))); 322 assertEval("A<String> as = new A<>(\"low\");", 323 ste(MAIN_SNIPPET, VALID, VALID, false, null), 324 ste(assn, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 325 assertEval("as.get();", "\"low\""); 326 assertUnresolvedDependencies(a, 0); 327 assertActiveKeys(); 328 } 329 330 public void testForwardVarToClassExtendsImplements() { 331 DeclarationSnippet ik = classKey(assertEval("interface I { default int ii() { return 1; } }", added(VALID))); 332 DeclarationSnippet jk = classKey(assertEval("interface J { default int jj() { return 2; } }", added(VALID))); 333 DeclarationSnippet ck = classKey(assertEval("class C { int cc() { return 3; } }", added(VALID))); 334 DeclarationSnippet dk = classKey(assertEval("class D extends C implements I,J { int dd() { return g; } }", added(RECOVERABLE_DEFINED))); 335 DeclarationSnippet ek = classKey(assertEval("class E extends D { int ee() { return 5; } }", added(VALID))); 336 assertUnresolvedDependencies1(dk, RECOVERABLE_DEFINED, "variable g"); 337 assertEvalUnresolvedException("new D();", "D", 1, 0); 338 assertEvalUnresolvedException("new E();", "D", 1, 0); 339 VarSnippet g = varKey(assertEval("int g = 10;", "10", 340 added(VALID), 341 ste(dk, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET))); 342 assertEval("E e = new E();"); 343 assertDrop(g, 344 ste(g, VALID, DROPPED, true, null), 345 ste(dk, VALID, RECOVERABLE_DEFINED, false, g)); 346 assertEvalUnresolvedException("new D();", "D", 1, 0); 347 assertEvalUnresolvedException("new E();", "D", 1, 0); 348 assertEval("e.ee();", "5"); 349 assertEvalUnresolvedException("e.dd();", "D", 1, 0); 350 assertEval("e.cc();", "3"); 351 assertEval("e.jj();", "2"); 352 assertEval("e.ii();", "1"); 353 assertActiveKeys(); 354 } 355 356 public void testForwardVarToInterface() { 357 DeclarationSnippet i = classKey(assertEval("interface I { default int f() { return x; } }", added(RECOVERABLE_DEFINED))); 358 assertUnresolvedDependencies1(i, RECOVERABLE_DEFINED, "variable x"); 359 DeclarationSnippet c = classKey(assertEval("class C implements I { int z() { return 2; } }", added(VALID))); 360 assertEval("C c = new C();"); 361 assertEval("c.z();", "2"); 362 assertEvalUnresolvedException("c.f()", "I", 1, 0); 363 Snippet g = varKey(assertEval("int x = 55;", "55", 364 added(VALID), 365 ste(i, RECOVERABLE_DEFINED, VALID, false, null))); 366 assertEval("c.f();", "55"); 367 assertUnresolvedDependencies(i, 0); 368 assertActiveKeys(); 369 } 370 371 public void testForwardVarToEnum() { 372 DeclarationSnippet a = classKey(assertEval("enum E { Q, W, E; float ff() { return fff; } }", added(RECOVERABLE_DEFINED))); 373 assertUnresolvedDependencies1(a, RECOVERABLE_DEFINED, "variable fff"); 374 Snippet g = varKey(assertEval("float fff = 4.5f;", "4.5", 375 added(VALID), 376 ste(a, RECOVERABLE_DEFINED, VALID, false, null))); 377 assertEval("E.Q.ff();", "4.5"); 378 assertEval("double fff = 3.3;", "3.3", null, 379 DiagCheck.DIAG_OK, 380 DiagCheck.DIAG_ERROR, 381 ste(MAIN_SNIPPET, VALID, VALID, true, null), 382 ste(g, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 383 ste(a, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET)); 384 assertUnresolvedDependencies(a, 0); 385 assertActiveKeys(); 386 } 387 388 public void testForwardMethodToClass() { 389 DeclarationSnippet a = classKey(assertEval("class A { int f() { return g(); } }", added(RECOVERABLE_DEFINED))); 390 assertUnresolvedDependencies1(a, RECOVERABLE_DEFINED, "method g()"); 391 assertEval("A foo() { return null; }"); 392 assertEvalUnresolvedException("new A();", "A", 1, 0); 393 Snippet g = methodKey(assertEval("int g() { return 10; }", 394 added(VALID), 395 ste(a, RECOVERABLE_DEFINED, VALID, false, null))); 396 assertEval("new A().f();", "10"); 397 assertEval("double g() { return 10; }", 398 DiagCheck.DIAG_OK, 399 DiagCheck.DIAG_ERROR, 400 ste(MAIN_SNIPPET, VALID, VALID, true, null), 401 ste(g, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 402 ste(a, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET)); 403 assertUnresolvedDependencies(a, 0); 404 assertActiveKeys(); 405 } 406 407 public void testForwardClassToClass1() { 408 Snippet a = classKey(assertEval("class A { B b = new B(); }", added(RECOVERABLE_NOT_DEFINED))); 409 assertDeclareFail("new A().b;", "compiler.err.cant.resolve.location"); 410 411 Snippet b = classKey(assertEval("class B { public String toString() { return \"B\"; } }", 412 added(VALID), 413 ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null))); 414 assertEval("new A().b;", "B"); 415 assertEval("interface B { }", 416 DiagCheck.DIAG_OK, 417 DiagCheck.DIAG_ERROR, 418 ste(MAIN_SNIPPET, VALID, VALID, true, null), 419 ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 420 ste(a, VALID, RECOVERABLE_DEFINED, true, MAIN_SNIPPET)); 421 assertEvalUnresolvedException("new A().b;", "A", 0, 1); 422 assertActiveKeys(); 423 } 424 425 public void testForwardClassToClass2() { 426 Snippet a = classKey(assertEval("class A extends B { }", added(RECOVERABLE_NOT_DEFINED))); 427 assertDeclareFail("new A();", "compiler.err.cant.resolve.location"); 428 429 Snippet b = classKey(assertEval("class B { public String toString() { return \"B\"; } }", 430 added(VALID), 431 ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null))); 432 assertEval("new A();", "B"); 433 assertEval("interface B { }", 434 DiagCheck.DIAG_OK, 435 DiagCheck.DIAG_ERROR, 436 ste(MAIN_SNIPPET, VALID, VALID, true, null), 437 ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 438 ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET)); 439 assertDeclareFail("new A();", "compiler.err.cant.resolve.location"); 440 assertActiveKeys(); 441 } 442 443 public void testForwardClassToClass3() { 444 Snippet a = classKey(assertEval("interface A extends B { static int f() { return 10; } }", added(RECOVERABLE_NOT_DEFINED))); 445 assertDeclareFail("A.f();", "compiler.err.cant.resolve.location"); 446 447 Snippet b = classKey(assertEval("interface B { }", 448 added(VALID), 449 ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null))); 450 assertEval("A.f();", "10"); 451 assertEval("class B { }", 452 DiagCheck.DIAG_OK, 453 DiagCheck.DIAG_ERROR, 454 ste(MAIN_SNIPPET, VALID, VALID, true, null), 455 ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 456 ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET)); 457 assertDeclareFail("A.f();", "compiler.err.cant.resolve.location"); 458 assertActiveKeys(); 459 } 460 461 public void testImportDeclare() { 462 Snippet singleImport = importKey(assertEval("import java.util.List;", added(VALID))); 463 Snippet importOnDemand = importKey(assertEval("import java.util.*;", added(VALID))); 464 Snippet singleStaticImport = importKey(assertEval("import static java.lang.Math.abs;", added(VALID))); 465 Snippet staticImportOnDemand = importKey(assertEval("import static java.lang.Math.*;", added(VALID))); 466 assertEval("import java.util.List; //again", 467 ste(MAIN_SNIPPET, VALID, VALID, false, null), 468 ste(singleImport, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 469 assertEval("import java.util.*; //again", 470 ste(MAIN_SNIPPET, VALID, VALID, false, null), 471 ste(importOnDemand, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 472 assertEval("import static java.lang.Math.abs; //again", 473 ste(MAIN_SNIPPET, VALID, VALID, false, null), 474 ste(singleStaticImport, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 475 assertEval("import static java.lang.Math.*; //again", 476 ste(MAIN_SNIPPET, VALID, VALID, false, null), 477 ste(staticImportOnDemand, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); 478 assertActiveKeys(); 479 } 480 481 public void testForwardVariable() { 482 assertEval("int f() { return x; }", added(RECOVERABLE_DEFINED)); 483 assertEvalUnresolvedException("f();", "f", 1, 0); 484 assertActiveKeys(); 485 } 486 487 public void testLocalClassInUnresolved() { 488 Snippet f = methodKey(assertEval("void f() { class A {} g(); }", added(RECOVERABLE_DEFINED))); 489 assertEval("void g() {}", 490 added(VALID), 491 ste(f, RECOVERABLE_DEFINED, VALID, false, null)); 492 assertEval("f();", ""); 493 } 494 495 @Test(enabled = false) // TODO 8129420 496 public void testLocalClassEvolve() { 497 Snippet j = methodKey(assertEval("Object j() { return null; }", added(VALID))); 498 assertEval("Object j() { class B {}; return null; }", 499 ste(MAIN_SNIPPET, VALID, VALID, false, null)); 500 assertEval("Object j() { class B {}; return new B(); }", 501 ste(MAIN_SNIPPET, VALID, VALID, false, null)); 502 assertEval("j().getClass().getSimpleName();", "\"B\""); 503 assertEval("Object j() { class B { int p; public String toString() { return \"Yep\";} }; return new B(); }", 504 ste(MAIN_SNIPPET, VALID, VALID, false, null)); 505 assertEval("j().getClass().getSimpleName();", "\"B\""); 506 assertEval("j();", "Yep"); 507 } 508 509 public void testForwardSingleImportMethodToMethod() { 510 DeclarationSnippet string = methodKey(assertEval("String string() { return format(\"string\"); }", 511 added(RECOVERABLE_DEFINED))); 512 assertUnresolvedDependencies1(string, RECOVERABLE_DEFINED, "method format(java.lang.String)"); 513 assertEvalUnresolvedException("string();", "string", 1, 0); 514 assertEval("import static java.lang.String.format;", 515 added(VALID), 516 ste(string, RECOVERABLE_DEFINED, VALID, false, null)); 517 assertEval("string();", "\"string\""); 518 519 assertEval("double format(String s) { return 0; }", 520 DiagCheck.DIAG_OK, 521 DiagCheck.DIAG_ERROR, 522 added(VALID), 523 ste(string, VALID, RECOVERABLE_DEFINED, false, null)); 524 assertEvalUnresolvedException("string();", "string", 0, 1); 525 assertActiveKeys(); 526 } 527 528 public void testForwardImportMethodOnDemandToMethod() { 529 DeclarationSnippet string = methodKey(assertEval("String string() { return format(\"string\"); }", 530 added(RECOVERABLE_DEFINED))); 531 assertUnresolvedDependencies1(string, RECOVERABLE_DEFINED, "method format(java.lang.String)"); 532 assertEvalUnresolvedException("string();", "string", 1, 0); 533 assertEval("import static java.lang.String.*;", 534 added(VALID), 535 ste(string, RECOVERABLE_DEFINED, VALID, false, null)); 536 assertEval("string();", "\"string\""); 537 538 assertEval("double format(String s) { return 0; }", 539 DiagCheck.DIAG_OK, 540 DiagCheck.DIAG_ERROR, 541 added(VALID), 542 ste(string, VALID, RECOVERABLE_DEFINED, false, null)); 543 assertEvalUnresolvedException("string();", "string", 0, 1); 544 assertActiveKeys(); 545 } 546 547 public void testForwardSingleImportFieldToMethod() { 548 DeclarationSnippet pi = methodKey(assertEval("double pi() { return PI; }", 549 added(RECOVERABLE_DEFINED))); 550 assertUnresolvedDependencies1(pi, RECOVERABLE_DEFINED, "variable PI"); 551 assertEvalUnresolvedException("pi();", "pi", 1, 0); 552 assertEval("import static java.lang.Math.PI;", 553 added(VALID), 554 ste(pi, RECOVERABLE_DEFINED, VALID, false, null)); 555 assertEval("Math.abs(pi() - 3.1415) < 0.001;", "true"); 556 557 assertEval("String PI;", 558 DiagCheck.DIAG_OK, 559 DiagCheck.DIAG_ERROR, 560 added(VALID), 561 ste(pi, VALID, RECOVERABLE_DEFINED, false, null)); 562 assertEvalUnresolvedException("pi();", "pi", 0, 1); 563 assertActiveKeys(); 564 } 565 566 public void testForwardImportFieldOnDemandToMethod() { 567 DeclarationSnippet pi = methodKey(assertEval("double pi() { return PI; }", 568 added(RECOVERABLE_DEFINED))); 569 assertUnresolvedDependencies1(pi, RECOVERABLE_DEFINED, "variable PI"); 570 assertEvalUnresolvedException("pi();", "pi", 1, 0); 571 assertEval("import static java.lang.Math.*;", 572 added(VALID), 573 ste(pi, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET)); 574 assertEval("Math.abs(pi() - 3.1415) < 0.001;", "true"); 575 576 assertEval("String PI;", 577 DiagCheck.DIAG_OK, 578 DiagCheck.DIAG_ERROR, 579 added(VALID), 580 ste(pi, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET)); 581 assertEvalUnresolvedException("pi();", "pi", 0, 1); 582 assertActiveKeys(); 583 } 584 585 public void testForwardSingleImportMethodToClass1() { 586 PersistentSnippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }", 587 added(RECOVERABLE_DEFINED))); 588 assertEvalUnresolvedException("new A();", "A", 1, 0); 589 assertEval("import static java.lang.String.format;", 590 added(VALID), 591 ste(a, RECOVERABLE_DEFINED, VALID, false, null)); 592 assertEval("new A().s;", "\"10\""); 593 PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }", 594 DiagCheck.DIAG_OK, 595 DiagCheck.DIAG_ERROR, 596 added(VALID), 597 ste(a, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET))); 598 assertEvalUnresolvedException("new A();", "A", 0, 1); 599 assertActiveKeys(); 600 assertDrop(format, 601 ste(format, VALID, DROPPED, true, null), 602 ste(a, RECOVERABLE_DEFINED, VALID, false, format)); 603 } 604 605 public void testForwardSingleImportMethodToClass2() { 606 PersistentSnippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }", 607 added(RECOVERABLE_DEFINED))); 608 assertEvalUnresolvedException("new A();", "A", 1, 0); 609 assertEval("import static java.lang.String.format;", 610 added(VALID), 611 ste(a, RECOVERABLE_DEFINED, VALID, false, null)); 612 assertEval("new A().s();", "\"10\""); 613 PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }", 614 DiagCheck.DIAG_OK, 615 DiagCheck.DIAG_ERROR, 616 added(VALID), 617 ste(a, VALID, RECOVERABLE_DEFINED, false, null))); 618 assertEvalUnresolvedException("new A();", "A", 0, 1); 619 assertActiveKeys(); 620 assertDrop(format, 621 ste(format, VALID, DROPPED, true, null), 622 ste(a, RECOVERABLE_DEFINED, VALID, false, format)); 623 } 624 625 public void testForwardSingleImportClassToClass1() { 626 PersistentSnippet a = classKey(assertEval("class A { static List<Integer> list; }", 627 added(RECOVERABLE_NOT_DEFINED))); 628 assertDeclareFail("new A();", "compiler.err.cant.resolve.location"); 629 assertEval("import java.util.List;", 630 added(VALID), 631 ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null)); 632 assertEval("import java.util.Arrays;", added(VALID)); 633 assertEval("A.list = Arrays.asList(1, 2, 3);", "[1, 2, 3]"); 634 635 PersistentSnippet list = classKey(assertEval("class List {}", 636 DiagCheck.DIAG_OK, 637 DiagCheck.DIAG_ERROR, 638 added(VALID), 639 ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null))); 640 assertDeclareFail("A.list = Arrays.asList(1, 2, 3);", "compiler.err.already.defined.static.single.import"); 641 assertActiveKeys(); 642 assertDrop(list, 643 ste(list, VALID, DROPPED, true, null), 644 ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, list)); 645 } 646 647 public void testForwardSingleImportClassToClass2() { 648 PersistentSnippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }", 649 added(RECOVERABLE_NOT_DEFINED))); 650 assertDeclareFail("new A();", "compiler.err.cant.resolve.location"); 651 assertEval("import java.util.ArrayList;", 652 added(VALID), 653 ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET)); 654 Snippet vara = varKey(assertEval("A a = new A();", "[]")); 655 656 PersistentSnippet arraylist = classKey(assertEval("class ArrayList {}", 657 DiagCheck.DIAG_OK, 658 DiagCheck.DIAG_ERROR, 659 added(VALID), 660 ste(clsA, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET), 661 ste(vara, VALID, RECOVERABLE_NOT_DEFINED, true, clsA))); 662 assertDeclareFail("A a = new A();", "compiler.err.cant.resolve.location", 663 ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, REJECTED, false, null), 664 ste(vara, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET)); 665 assertActiveKeys(); 666 assertDrop(arraylist, 667 ste(arraylist, VALID, DROPPED, true, null), 668 ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, arraylist)); 669 } 670 671 public void testForwardImportOnDemandMethodToClass1() { 672 PersistentSnippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }", 673 added(RECOVERABLE_DEFINED))); 674 assertEvalUnresolvedException("new A();", "A", 1, 0); 675 assertEval("import static java.lang.String.*;", 676 added(VALID), 677 ste(a, RECOVERABLE_DEFINED, VALID, false, null)); 678 assertEval("A x = new A();"); 679 assertEval("x.s;", "\"10\""); 680 PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }", 681 DiagCheck.DIAG_OK, 682 DiagCheck.DIAG_ERROR, 683 added(VALID), 684 ste(a, VALID, RECOVERABLE_DEFINED, false, null))); 685 assertEvalUnresolvedException("new A();", "A", 0, 1); 686 assertActiveKeys(); 687 assertDrop(format, 688 ste(format, VALID, DROPPED, true, null), 689 ste(a, RECOVERABLE_DEFINED, VALID, false, format)); 690 assertEval("x.s;", "\"10\""); 691 } 692 693 public void testForwardImportOnDemandMethodToClass2() { 694 PersistentSnippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }", 695 added(RECOVERABLE_DEFINED))); 696 assertEvalUnresolvedException("new A();", "A", 1, 0); 697 assertEval("import static java.lang.String.*;", 698 added(VALID), 699 ste(a, RECOVERABLE_DEFINED, VALID, false, null)); 700 assertEval("new A().s();", "\"10\""); 701 PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }", 702 DiagCheck.DIAG_OK, 703 DiagCheck.DIAG_ERROR, 704 added(VALID), 705 ste(a, VALID, RECOVERABLE_DEFINED, false, null))); 706 assertEvalUnresolvedException("new A();", "A", 0, 1); 707 assertActiveKeys(); 708 assertDrop(format, 709 ste(format, VALID, DROPPED, true, null), 710 ste(a, RECOVERABLE_DEFINED, VALID, false, format)); 711 } 712 713 public void testForwardImportOnDemandClassToClass1() { 714 PersistentSnippet a = classKey(assertEval("class A { static List<Integer> list; }", 715 added(RECOVERABLE_NOT_DEFINED))); 716 assertDeclareFail("new A();", "compiler.err.cant.resolve.location"); 717 assertEval("import java.util.*;", 718 added(VALID), 719 ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null)); 720 assertEval("A.list = Arrays.asList(1, 2, 3);", "[1, 2, 3]"); 721 722 PersistentSnippet list = classKey(assertEval("class List {}", 723 DiagCheck.DIAG_OK, 724 DiagCheck.DIAG_ERROR, 725 added(VALID), 726 ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null))); 727 assertDeclareFail("A.list = Arrays.asList(1, 2, 3);", "compiler.err.cant.resolve.location"); 728 assertActiveKeys(); 729 assertDrop(list, 730 ste(list, VALID, DROPPED, true, null), 731 ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, list)); 732 } 733 734 public void testForwardImportOnDemandClassToClass2() { 735 PersistentSnippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }", 736 added(RECOVERABLE_NOT_DEFINED))); 737 assertDeclareFail("new A();", "compiler.err.cant.resolve.location"); 738 assertEval("import java.util.*;", 739 added(VALID), 740 ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET)); 741 Snippet vara = varKey(assertEval("A a = new A();", "[]")); 742 743 PersistentSnippet arraylist = classKey(assertEval("class ArrayList {}", 744 DiagCheck.DIAG_OK, 745 DiagCheck.DIAG_ERROR, 746 added(VALID), 747 ste(clsA, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET), 748 ste(vara, VALID, RECOVERABLE_NOT_DEFINED, true, clsA))); 749 assertDeclareFail("new A();", "compiler.err.cant.resolve.location"); 750 assertActiveKeys(); 751 assertDrop(arraylist, 752 ste(arraylist, VALID, DROPPED, true, null), 753 ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, arraylist), 754 ste(vara, RECOVERABLE_NOT_DEFINED, VALID, true, clsA)); 755 } 756 757 public void testForwardSingleImportFieldToClass1() { 758 PersistentSnippet a = classKey(assertEval("class A { static double pi() { return PI; } }", 759 added(RECOVERABLE_DEFINED))); 760 assertEvalUnresolvedException("new A();", "A", 1, 0); 761 assertEval("import static java.lang.Math.PI;", 762 added(VALID), 763 ste(a, RECOVERABLE_DEFINED, VALID, false, null)); 764 assertEval("Math.abs(A.pi() - 3.1415) < 0.001;", "true"); 765 766 PersistentSnippet list = varKey(assertEval("String PI;", 767 DiagCheck.DIAG_OK, 768 DiagCheck.DIAG_ERROR, 769 added(VALID), 770 ste(a, VALID, RECOVERABLE_DEFINED, false, null))); 771 assertEvalUnresolvedException("new A();", "A", 0, 1); 772 assertActiveKeys(); 773 assertDrop(list, 774 ste(list, VALID, DROPPED, true, null), 775 ste(a, RECOVERABLE_DEFINED, VALID, false, list)); 776 } 777 778 public void testForwardSingleImportFieldToClass2() { 779 PersistentSnippet a = classKey(assertEval("class A { static double pi = PI; }", 780 added(RECOVERABLE_DEFINED))); 781 assertEvalUnresolvedException("new A();", "A", 1, 0); 782 assertEval("import static java.lang.Math.PI;", 783 added(VALID), 784 ste(a, RECOVERABLE_DEFINED, VALID, true, null)); 785 assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true"); 786 787 PersistentSnippet list = varKey(assertEval("String PI;", 788 DiagCheck.DIAG_OK, 789 DiagCheck.DIAG_ERROR, 790 added(VALID), 791 ste(a, VALID, RECOVERABLE_DEFINED, true, null))); 792 assertEvalUnresolvedException("new A();", "A", 0, 1); 793 assertActiveKeys(); 794 assertDrop(list, 795 ste(list, VALID, DROPPED, true, null), 796 ste(a, RECOVERABLE_DEFINED, VALID, true, list)); 797 } 798 799 public void testForwardImportOnDemandFieldToClass1() { 800 PersistentSnippet a = classKey(assertEval("class A { static double pi() { return PI; } }", 801 added(RECOVERABLE_DEFINED))); 802 assertEvalUnresolvedException("new A();", "A", 1, 0); 803 assertEval("import static java.lang.Math.*;", 804 added(VALID), 805 ste(a, RECOVERABLE_DEFINED, VALID, false, null)); 806 assertEval("Math.abs(A.pi() - 3.1415) < 0.001;", "true"); 807 808 PersistentSnippet list = varKey(assertEval("String PI;", 809 DiagCheck.DIAG_OK, 810 DiagCheck.DIAG_ERROR, 811 added(VALID), 812 ste(a, VALID, RECOVERABLE_DEFINED, false, null))); 813 assertEvalUnresolvedException("new A();", "A", 0, 1); 814 assertActiveKeys(); 815 assertDrop(list, 816 ste(list, VALID, DROPPED, true, null), 817 ste(a, RECOVERABLE_DEFINED, VALID, false, list)); 818 } 819 820 public void testForwardImportOnDemandFieldToClass2() { 821 PersistentSnippet a = classKey(assertEval("class A { static double pi = PI; }", 822 added(RECOVERABLE_DEFINED))); 823 assertEvalUnresolvedException("new A();", "A", 1, 0); 824 assertEval("import static java.lang.Math.*;", 825 added(VALID), 826 ste(a, RECOVERABLE_DEFINED, VALID, true, null)); 827 assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true"); 828 829 PersistentSnippet list = varKey(assertEval("String PI;", 830 DiagCheck.DIAG_OK, 831 DiagCheck.DIAG_ERROR, 832 added(VALID), 833 ste(a, VALID, RECOVERABLE_DEFINED, true, null))); 834 assertEvalUnresolvedException("new A();", "A", 0, 1); 835 assertActiveKeys(); 836 assertDrop(list, 837 ste(list, VALID, DROPPED, true, null), 838 ste(a, RECOVERABLE_DEFINED, VALID, true, list)); 839 assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true"); 840 } 841 842 public void testReplaceCausesMethodReferenceError() { 843 Snippet l = classKey(assertEval("interface Logger { public void log(String message); }", added(VALID))); 844 Snippet v = varKey(assertEval("Logger l = System.out::println;", added(VALID))); 845 assertEval("interface Logger { public boolean accept(String message); }", 846 DiagCheck.DIAG_OK, 847 DiagCheck.DIAG_ERROR, 848 ste(MAIN_SNIPPET, VALID, VALID, true, null), 849 ste(l, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 850 ste(v, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET)); 851 } 852 853 public void testReplaceCausesClassCompilationError() { 854 Snippet l = classKey(assertEval("interface L { }", added(VALID))); 855 Snippet c = classKey(assertEval("class C implements L { }", added(VALID))); 856 assertEval("interface L { void m(); }", 857 DiagCheck.DIAG_OK, 858 DiagCheck.DIAG_ERROR, 859 ste(MAIN_SNIPPET, VALID, VALID, true, null), 860 ste(l, VALID, OVERWRITTEN, false, MAIN_SNIPPET), 861 ste(c, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET)); 862 } 863 864 public void testOverwriteNoUpdate() { 865 String xsi = "int x = 5;"; 866 String xsd = "double x = 3.14159;"; 867 VarSnippet xi = varKey(assertEval(xsi, added(VALID))); 868 String ms1 = "double m(Integer i) { return i + x; }"; 869 String ms2 = "double m(java.lang.Integer i) { return i + x; }"; 870 MethodSnippet k1 = methodKey(assertEval(ms1, added(VALID))); 871 VarSnippet xd = varKey(assertEval(xsd, 872 ste(MAIN_SNIPPET, VALID, VALID, true, null), 873 ste(xi, VALID, OVERWRITTEN, false, MAIN_SNIPPET))); 874 MethodSnippet k2 = methodKey(assertEval(ms2, 875 ste(MAIN_SNIPPET, VALID, VALID, true, null), //TODO: technically, should be false 876 ste(k1, VALID, OVERWRITTEN, false, MAIN_SNIPPET))); 877 VarSnippet xi2 = varKey(assertEval(xsi, 878 ste(MAIN_SNIPPET, VALID, VALID, true, null), 879 ste(xd, VALID, OVERWRITTEN, false, MAIN_SNIPPET))); 880 varKey(assertEval(xsd, 881 ste(MAIN_SNIPPET, VALID, VALID, true, null), 882 ste(xi2, VALID, OVERWRITTEN, false, MAIN_SNIPPET))); 883 } 884} 885