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 TestTry 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.op.CoreOp; 35 import jdk.incubator.code.Op; 36 import jdk.incubator.code.interpreter.Interpreter; 37 import java.lang.invoke.MethodHandles; 38 import java.lang.reflect.Method; 39 import jdk.incubator.code.CodeReflection; 40 import java.util.ArrayList; 41 import java.util.List; 42 import java.util.Optional; 43 import java.util.function.Consumer; 44 import java.util.function.IntConsumer; 45 import java.util.stream.Stream; 46 47 public class TestTry { 48 49 @CodeReflection 50 public static void catching(IntConsumer c) { 51 try { 52 c.accept(0); 53 c.accept(-1); 54 } catch (IllegalStateException e) { 55 consume(e); 56 c.accept(1); 57 c.accept(-1); 58 } catch (IllegalArgumentException e) { 59 consume(e); 60 c.accept(2); 61 c.accept(-1); 62 } 63 c.accept(3); 64 c.accept(-1); 65 } 66 67 @Test 68 public void testCatching() { 69 CoreOp.FuncOp f = getFuncOp("catching"); 70 71 f.writeTo(System.out); 72 73 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 74 75 lf.writeTo(System.out); 76 77 Consumer<IntConsumer> test = testConsumer( 78 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c), 79 TestTry::catching); 80 81 test.accept(i -> { 82 }); 83 test.accept(i -> { 84 if (i == 0) throw new IllegalStateException(); 85 }); 86 test.accept(i -> { 87 if (i == 0) throw new IllegalArgumentException(); 88 }); 89 test.accept(i -> { 90 if (i == 0) throw new NullPointerException(); 91 }); 92 test.accept(i -> { 93 if (i == 0) throw new IllegalStateException(); 94 if (i == 1) throw new RuntimeException(); 95 }); 96 test.accept(i -> { 97 if (i == 0) throw new IllegalArgumentException(); 98 if (i == 2) throw new RuntimeException(); 99 }); 100 test.accept(i -> { 101 if (i == 3) throw new IllegalStateException(); 102 }); 103 } 104 105 106 @CodeReflection 107 public static void catchThrowable(IntConsumer c) { 108 try { 109 c.accept(0); 110 c.accept(-1); 111 } catch (IllegalStateException e) { 112 consume(e); 113 c.accept(1); 114 c.accept(-1); 115 } catch (Throwable e) { 116 consume(e); 117 c.accept(2); 118 c.accept(-1); 119 } 120 c.accept(3); 121 c.accept(-1); 122 } 123 124 @Test 125 public void testCatchThrowable() { 126 CoreOp.FuncOp f = getFuncOp("catchThrowable"); 127 128 f.writeTo(System.out); 129 130 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 131 132 lf.writeTo(System.out); 133 134 Consumer<IntConsumer> test = testConsumer( 135 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c), 136 TestTry::catchThrowable); 137 138 test.accept(i -> { 139 }); 140 test.accept(i -> { 141 if (i == 0) throw new IllegalStateException(); 142 }); 143 test.accept(i -> { 144 if (i == 0) throw new RuntimeException(); 145 }); 146 test.accept(i -> { 147 if (i == 0) throw new IllegalStateException(); 148 if (i == 1) throw new RuntimeException(); 149 }); 150 test.accept(i -> { 151 if (i == 0) throw new RuntimeException(); 152 if (i == 2) throw new RuntimeException(); 153 }); 154 test.accept(i -> { 155 if (i == 3) throw new IllegalStateException(); 156 }); 157 } 158 159 160 @CodeReflection 161 public static void catchNested(IntConsumer c) { 162 try { 163 c.accept(0); 164 c.accept(-1); 165 try { 166 c.accept(1); 167 c.accept(-1); 168 } catch (IllegalStateException e) { 169 consume(e); 170 c.accept(2); 171 c.accept(-1); 172 } 173 c.accept(3); 174 c.accept(-1); 175 } catch (IllegalArgumentException e) { 176 consume(e); 177 c.accept(4); 178 c.accept(-1); 179 } 180 c.accept(5); 181 c.accept(-1); 182 } 183 184 @Test 185 public void testCatchNested() { 186 CoreOp.FuncOp f = getFuncOp("catchNested"); 187 188 f.writeTo(System.out); 189 190 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 191 192 lf.writeTo(System.out); 193 194 Consumer<IntConsumer> test = testConsumer( 195 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c), 196 TestTry::catchNested); 197 198 test.accept(i -> { 199 }); 200 test.accept(i -> { 201 if (i == 0) throw new IllegalStateException(); 202 }); 203 test.accept(i -> { 204 if (i == 0) throw new IllegalArgumentException(); 205 }); 206 test.accept(i -> { 207 if (i == 1) throw new IllegalStateException(); 208 }); 209 test.accept(i -> { 210 if (i == 1) throw new IllegalArgumentException(); 211 }); 212 test.accept(i -> { 213 if (i == 1) throw new IllegalStateException(); 214 if (i == 2) throw new IllegalArgumentException(); 215 }); 216 test.accept(i -> { 217 if (i == 1) throw new IllegalStateException(); 218 if (i == 2) throw new RuntimeException(); 219 }); 220 test.accept(i -> { 221 if (i == 3) throw new IllegalArgumentException(); 222 }); 223 test.accept(i -> { 224 if (i == 3) throw new RuntimeException(); 225 }); 226 test.accept(i -> { 227 if (i == 3) throw new IllegalArgumentException(); 228 if (i == 4) throw new RuntimeException(); 229 }); 230 test.accept(i -> { 231 if (i == 5) throw new RuntimeException(); 232 }); 233 } 234 235 236 static CoreOp.FuncOp getFuncOp(String name) { 237 Optional<Method> om = Stream.of(TestTry.class.getDeclaredMethods()) 238 .filter(m -> m.getName().equals(name)) 239 .findFirst(); 240 241 Method m = om.get(); 242 return Op.ofMethod(m).get(); 243 } 244 245 static void consume(Throwable e) { 246 } 247 248 static Consumer<IntConsumer> testConsumer(Consumer<IntConsumer> actualR, Consumer<IntConsumer> expectedR) { 249 return c -> { 250 List<Integer> actual = new ArrayList<>(); 251 IntConsumer actualC = actual::add; 252 Throwable actualT = null; 253 try { 254 actualR.accept(actualC.andThen(c)); 255 } catch (Interpreter.InterpreterException e) { 256 throw e; 257 } catch (Throwable t) { 258 actualT = t; 259 if (t instanceof AssertionError) { 260 t.printStackTrace(); 261 } 262 } 263 264 List<Integer> expected = new ArrayList<>(); 265 IntConsumer expectedC = expected::add; 266 Throwable expectedT = null; 267 try { 268 expectedR.accept(expectedC.andThen(c)); 269 } catch (Throwable t) { 270 expectedT = t; 271 } 272 273 Assert.assertEquals( 274 actualT != null ? actualT.getClass() : null, 275 expectedT != null ? expectedT.getClass() : null); 276 Assert.assertEquals(actual, expected); 277 }; 278 } 279 }