1 /* 2 * Copyright (c) 2024, 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 * @modules jdk.incubator.code 27 * @run testng TestTryNested 28 */ 29 30 import jdk.incubator.code.Op; 31 import org.testng.Assert; 32 import org.testng.annotations.Test; 33 34 import jdk.incubator.code.OpTransformer; 35 import jdk.incubator.code.dialect.core.CoreOp; 36 import jdk.incubator.code.interpreter.Interpreter; 37 38 import java.lang.invoke.MethodHandles; 39 import java.lang.reflect.Method; 40 import jdk.incubator.code.CodeReflection; 41 import java.util.ArrayList; 42 import java.util.List; 43 import java.util.Optional; 44 import java.util.function.Consumer; 45 import java.util.function.IntConsumer; 46 import java.util.stream.Stream; 47 48 public class TestTryNested { 49 @CodeReflection 50 public static void tryCatchFinally(IntConsumer c, int i) { 51 try { 52 try { 53 if (i == 0) { 54 return; 55 } 56 c.accept(0); 57 } catch (IllegalStateException e) { 58 if (i == 1) { 59 return; 60 } 61 c.accept(1); 62 } finally { 63 if (i == 2) { 64 return; 65 } 66 c.accept(2); 67 } 68 if (i == 3) { 69 return; 70 } 71 c.accept(3); 72 } catch (IllegalStateException e) { 73 if (i == 4) { 74 return; 75 } 76 c.accept(4); 77 } finally { 78 if (i == 5) { 79 return; 80 } 81 c.accept(5); 82 } 83 c.accept(6); 84 } 85 86 @Test 87 public void testCatchFinally() { 88 CoreOp.FuncOp f = getFuncOp("tryCatchFinally"); 89 90 System.out.println(f.toText()); 91 92 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 93 94 System.out.println(lf.toText()); 95 96 for (int ra = -1; ra < 6; ra++) { 97 int fra = ra; 98 99 Consumer<IntConsumer> test = testConsumer( 100 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c, fra), 101 c -> tryCatchFinally(c, fra) 102 ); 103 104 test.accept(i -> {}); 105 for (int ea = 0; ea < 6; ea++) { 106 int fea = ea; 107 test.accept(i -> { 108 if (i == fea) throw new IllegalStateException(); 109 }); 110 test.accept(i -> { 111 if (i == fea) throw new RuntimeException(); 112 }); 113 } 114 } 115 } 116 117 118 @CodeReflection 119 public static void tryCatchBreak(IntConsumer c, int i) { 120 a: try { 121 try { 122 if (i == 0) { 123 break a; 124 } 125 c.accept(0); 126 } catch (IllegalStateException e) { 127 if (i == 1) { 128 break a; 129 } 130 c.accept(1); 131 } 132 if (i == 2) { 133 break a; 134 } 135 c.accept(2); 136 } catch (IllegalStateException e) { 137 if (i == 3) { 138 break a; 139 } 140 c.accept(3); 141 } 142 c.accept(4); 143 } 144 145 @Test 146 public void testCatchBreak() { 147 CoreOp.FuncOp f = getFuncOp("tryCatchBreak"); 148 149 System.out.println(f.toText()); 150 151 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 152 153 System.out.println(lf.toText()); 154 155 for (int ra = -1; ra < 4; ra++) { 156 int fra = ra; 157 158 Consumer<IntConsumer> test = testConsumer( 159 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c, fra), 160 c -> tryCatchBreak(c, fra) 161 ); 162 163 test.accept(i -> {}); 164 for (int ea = 0; ea <= 4; ea++) { 165 int fea = ea; 166 test.accept(i -> { 167 if (i == fea) throw new IllegalStateException(); 168 }); 169 test.accept(i -> { 170 if (i == fea) throw new RuntimeException(); 171 }); 172 } 173 } 174 } 175 176 @CodeReflection 177 public static void tryCatchFinallyBreak(IntConsumer c, int i) { 178 a: try { 179 try { 180 if (i == 0) { 181 break a; 182 } 183 c.accept(0); 184 } catch (IllegalStateException e) { 185 if (i == 1) { 186 break a; 187 } 188 c.accept(1); 189 } finally { 190 if (i == 2) { 191 break a; 192 } 193 c.accept(2); 194 } 195 if (i == 3) { 196 break a; 197 } 198 c.accept(3); 199 } catch (IllegalStateException e) { 200 if (i == 4) { 201 break a; 202 } 203 c.accept(4); 204 } finally { 205 if (i == 5) { 206 break a; 207 } 208 c.accept(5); 209 } 210 c.accept(6); 211 } 212 213 @Test 214 public void testCatchFinallyBreak() { 215 CoreOp.FuncOp f = getFuncOp("tryCatchFinallyBreak"); 216 217 System.out.println(f.toText()); 218 219 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 220 221 System.out.println(lf.toText()); 222 223 for (int ra = -1; ra < 6; ra++) { 224 int fra = ra; 225 226 Consumer<IntConsumer> test = testConsumer( 227 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c, fra), 228 c -> tryCatchFinallyBreak(c, fra) 229 ); 230 231 test.accept(i -> {}); 232 for (int ea = 0; ea <= 6; ea++) { 233 int fea = ea; 234 test.accept(i -> { 235 if (i == fea) throw new IllegalStateException(); 236 }); 237 test.accept(i -> { 238 if (i == fea) throw new RuntimeException(); 239 }); 240 } 241 } 242 } 243 244 245 @CodeReflection 246 public static void tryForLoop(IntConsumer c) { 247 for (int i = 0; i < 8; i++) { 248 c.accept(0); 249 try { 250 if (i == 4) { 251 continue; 252 } else if (i == 5) { 253 break; 254 } 255 c.accept(1); 256 } catch (IllegalStateException e) { 257 c.accept(2); 258 } 259 c.accept(3); 260 } 261 c.accept(4); 262 } 263 264 @Test 265 public void testTryForLoop() { 266 CoreOp.FuncOp f = getFuncOp("tryForLoop"); 267 268 System.out.println(f.toText()); 269 270 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 271 272 System.out.println(lf.toText()); 273 274 Consumer<IntConsumer> test = testConsumer( 275 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c), 276 TestTryNested::tryForLoop 277 ); 278 279 test.accept(i -> { }); 280 for (int ea = 0; ea <= 4; ea++) { 281 int fea = ea; 282 test.accept(i -> { 283 if (i == fea) throw new IllegalStateException(); 284 }); 285 test.accept(i -> { 286 if (i == fea) throw new RuntimeException(); 287 }); 288 } 289 } 290 291 @CodeReflection 292 public static void tryForLoopFinally(IntConsumer c) { 293 for (int i = 0; i < 8; i++) { 294 c.accept(0); 295 try { 296 if (i == 4) { 297 continue; 298 } else if (i == 5) { 299 break; 300 } 301 c.accept(1); 302 } finally { 303 c.accept(2); 304 } 305 c.accept(3); 306 } 307 c.accept(4); 308 } 309 310 @Test 311 public void testTryForLoopFinally() { 312 CoreOp.FuncOp f = getFuncOp("tryForLoopFinally"); 313 314 System.out.println(f.toText()); 315 316 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 317 318 System.out.println(lf.toText()); 319 320 Consumer<IntConsumer> test = testConsumer( 321 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c), 322 TestTryNested::tryForLoopFinally 323 ); 324 325 test.accept(i -> { }); 326 for (int ea = 0; ea <= 4; ea++) { 327 int fea = ea; 328 test.accept(i -> { 329 if (i == fea) throw new IllegalStateException(); 330 }); 331 test.accept(i -> { 332 if (i == fea) throw new RuntimeException(); 333 }); 334 } 335 } 336 337 338 @CodeReflection 339 public static void tryLabeledForLoop(IntConsumer c) { 340 a: for (int i = 0; i < 8; i++) { 341 c.accept(0); 342 b: { 343 try { 344 if (i == 4) { 345 continue a; 346 } else if (i == 5) { 347 break b; 348 } else if (i == 6) { 349 break a; 350 } 351 c.accept(1); 352 } finally { 353 c.accept(2); 354 } 355 c.accept(3); 356 } 357 c.accept(4); 358 } 359 c.accept(5); 360 } 361 362 @Test 363 public void testTryLabeledForLoop() { 364 CoreOp.FuncOp f = getFuncOp("tryLabeledForLoop"); 365 366 System.out.println(f.toText()); 367 368 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 369 370 System.out.println(lf.toText()); 371 372 Consumer<IntConsumer> test = testConsumer( 373 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c), 374 TestTryNested::tryLabeledForLoop 375 ); 376 377 test.accept(i -> { }); 378 } 379 380 381 @CodeReflection 382 public static void tryLambda(IntConsumer c, int i) { 383 try { 384 c.accept(0); 385 Runnable r = () -> { 386 if (i == 0) { 387 c.accept(1); 388 return; 389 } else { 390 c.accept(2); 391 } 392 c.accept(3); 393 }; 394 r.run(); 395 c.accept(4); 396 } finally { 397 c.accept(5); 398 } 399 } 400 401 @Test 402 public void testTryLambda() { 403 CoreOp.FuncOp f = getFuncOp("tryLambda"); 404 405 System.out.println(f.toText()); 406 407 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 408 409 System.out.println(lf.toText()); 410 411 for (int ra = 0; ra < 2; ra++) { 412 final int fra = ra; 413 Consumer<IntConsumer> test = testConsumer( 414 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c, fra), 415 c -> tryLambda(c, fra) 416 ); 417 test.accept(i -> { }); 418 } 419 } 420 421 422 static CoreOp.FuncOp getFuncOp(String name) { 423 Optional<Method> om = Stream.of(TestTryNested.class.getDeclaredMethods()) 424 .filter(m -> m.getName().equals(name)) 425 .findFirst(); 426 427 Method m = om.get(); 428 return Op.ofMethod(m).get(); 429 } 430 431 static Consumer<IntConsumer> testConsumer(Consumer<IntConsumer> actualR, Consumer<IntConsumer> expectedR) { 432 return c -> { 433 List<Integer> actual = new ArrayList<>(); 434 IntConsumer actualC = actual::add; 435 Throwable actualT = null; 436 try { 437 actualR.accept(actualC.andThen(c)); 438 } catch (Interpreter.InterpreterException e) { 439 throw e; 440 } catch (Throwable t) { 441 actualT = t; 442 if (t instanceof AssertionError) { 443 t.printStackTrace(); 444 } 445 } 446 447 List<Integer> expected = new ArrayList<>(); 448 IntConsumer expectedC = expected::add; 449 Throwable expectedT = null; 450 try { 451 expectedR.accept(expectedC.andThen(c)); 452 } catch (Throwable t) { 453 expectedT = t; 454 } 455 456 Assert.assertEquals( 457 actualT != null ? actualT.getClass() : null, 458 expectedT != null ? expectedT.getClass() : null); 459 Assert.assertEquals(actual, expected); 460 }; 461 } 462 }