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 TestTryFinally 28 */ 29 30 import org.testng.Assert; 31 import org.testng.annotations.Test; 32 33 import jdk.incubator.code.OpTransformer; 34 import jdk.incubator.code.dialect.core.CoreOp; 35 import jdk.incubator.code.Op; 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 TestTryFinally { 49 50 @CodeReflection 51 public static void tryCatchFinally(IntConsumer c) { 52 try { 53 c.accept(0); 54 c.accept(-1); 55 } catch (IllegalStateException e) { 56 c.accept(1); 57 c.accept(-1); 58 } finally { 59 c.accept(2); 60 c.accept(-1); 61 } 62 c.accept(3); 63 c.accept(-1); 64 } 65 66 @Test 67 public void testCatchFinally() { 68 CoreOp.FuncOp f = getFuncOp("tryCatchFinally"); 69 70 System.out.println(f.toText()); 71 72 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 73 74 System.out.println(lf.toText()); 75 76 Consumer<IntConsumer> test = testConsumer( 77 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c), 78 TestTryFinally::tryCatchFinally 79 ); 80 81 test(test); 82 } 83 84 85 @CodeReflection 86 public static void tryReturn(IntConsumer c) { 87 try { 88 c.accept(0); 89 c.accept(-1); 90 return; 91 } catch (IllegalStateException e) { 92 c.accept(1); 93 c.accept(-1); 94 } finally { 95 c.accept(2); 96 c.accept(-1); 97 } 98 c.accept(3); 99 c.accept(-1); 100 } 101 102 @Test 103 public void testTryReturn() { 104 CoreOp.FuncOp f = getFuncOp("tryReturn"); 105 106 System.out.println(f.toText()); 107 108 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 109 110 System.out.println(lf.toText()); 111 112 Consumer<IntConsumer> test = testConsumer( 113 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c), 114 TestTryFinally::tryReturn 115 ); 116 117 test(test); 118 } 119 120 121 @CodeReflection 122 public static void catchThrow(IntConsumer c) { 123 try { 124 c.accept(0); 125 c.accept(-1); 126 } catch (IllegalStateException e) { 127 c.accept(1); 128 c.accept(-1); 129 throw e; 130 } finally { 131 c.accept(2); 132 c.accept(-1); 133 } 134 c.accept(3); 135 c.accept(-1); 136 } 137 138 @Test 139 public void testCatchThrow() { 140 CoreOp.FuncOp f = getFuncOp("catchThrow"); 141 142 System.out.println(f.toText()); 143 144 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 145 146 System.out.println(lf.toText()); 147 148 Consumer<IntConsumer> test = testConsumer( 149 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c), 150 TestTryFinally::catchThrow 151 ); 152 153 test(test); 154 } 155 156 157 @CodeReflection 158 public static void finallyReturn(IntConsumer c) { 159 try { 160 c.accept(0); 161 c.accept(-1); 162 } catch (IllegalStateException e) { 163 c.accept(1); 164 c.accept(-1); 165 } finally { 166 c.accept(2); 167 c.accept(-1); 168 return; 169 } 170 } 171 172 @Test 173 public void testFinallyReturn() { 174 CoreOp.FuncOp f = getFuncOp("finallyReturn"); 175 176 System.out.println(f.toText()); 177 178 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 179 180 System.out.println(lf.toText()); 181 182 Consumer<IntConsumer> test = testConsumer( 183 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c), 184 TestTryFinally::finallyReturn 185 ); 186 187 test(test); 188 } 189 190 191 static void test(Consumer<IntConsumer> test) { 192 test.accept(i -> {}); 193 test.accept(i -> { 194 if (i == 0) throw new IllegalStateException(); 195 }); 196 test.accept(i -> { 197 if (i == 0) throw new RuntimeException(); 198 }); 199 test.accept(i -> { 200 if (i == 2) throw new RuntimeException(); 201 }); 202 test.accept(i -> { 203 if (i == 0) throw new IllegalStateException(); 204 if (i == 1) throw new RuntimeException(); 205 }); 206 test.accept(i -> { 207 if (i == 3) throw new RuntimeException(); 208 }); 209 } 210 211 static CoreOp.FuncOp getFuncOp(String name) { 212 Optional<Method> om = Stream.of(TestTryFinally.class.getDeclaredMethods()) 213 .filter(m -> m.getName().equals(name)) 214 .findFirst(); 215 216 Method m = om.get(); 217 return Op.ofMethod(m).get(); 218 } 219 220 static Consumer<IntConsumer> testConsumer(Consumer<IntConsumer> actualR, Consumer<IntConsumer> expectedR) { 221 return c -> { 222 List<Integer> actual = new ArrayList<>(); 223 IntConsumer actualC = actual::add; 224 Throwable actualT = null; 225 try { 226 actualR.accept(actualC.andThen(c)); 227 } catch (Interpreter.InterpreterException e) { 228 throw e; 229 } catch (Throwable t) { 230 actualT = t; 231 if (t instanceof AssertionError) { 232 t.printStackTrace(); 233 } 234 } 235 236 List<Integer> expected = new ArrayList<>(); 237 IntConsumer expectedC = expected::add; 238 Throwable expectedT = null; 239 try { 240 expectedR.accept(expectedC.andThen(c)); 241 } catch (Throwable t) { 242 expectedT = t; 243 } 244 245 Assert.assertEquals( 246 actualT != null ? actualT.getClass() : null, 247 expectedT != null ? expectedT.getClass() : null); 248 Assert.assertEquals(actual, expected); 249 }; 250 } 251 }