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