1 import jdk.incubator.code.*;
 2 import jdk.incubator.code.Reflect;
 3 import jdk.incubator.code.dialect.core.CoreOp;
 4 import jdk.incubator.code.dialect.core.FunctionType;
 5 import jdk.incubator.code.dialect.java.JavaType;
 6 import org.junit.jupiter.api.Assertions;
 7 import org.junit.jupiter.api.Test;
 8 
 9 import java.lang.reflect.Method;
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.function.IntBinaryOperator;
13 import java.util.function.IntUnaryOperator;
14 
15 /*
16  * @test
17  * @modules jdk.incubator.code
18  * @run junit TestSealOp
19  */
20 public class TestSealOp {
21 
22     @Reflect
23     static List<Integer> f(int i) {
24         return new ArrayList<>(i);
25     }
26 
27     @Test
28     void test0() throws NoSuchMethodException {
29         Method m = this.getClass().getDeclaredMethod("f", int.class);
30         CoreOp.FuncOp f = Op.ofMethod(m).get();
31         assertOpIsCopiedWhenAddedToBlock(f);
32     }
33 
34     @Test
35     void test1() {
36         IntUnaryOperator q = (@Reflect IntUnaryOperator) i -> i / 2;
37         Quoted quoted = Op.ofQuotable(q).get();
38         CoreOp.QuotedOp quotedOp = (CoreOp.QuotedOp) quoted.op().ancestorBody().ancestorOp();
39         CoreOp.FuncOp funcOp = (CoreOp.FuncOp) quotedOp.ancestorBody().ancestorOp();
40         assertOpIsCopiedWhenAddedToBlock(funcOp);
41     }
42 
43     @Test
44     void test2() {
45         CoreOp.ConstantOp constant = CoreOp.constant(JavaType.INT, 7);
46         constant.seal();
47         assertOpIsCopiedWhenAddedToBlock(constant);
48     }
49 
50     @Test
51     void test3() {
52         CoreOp.FuncOp funcOp = CoreOp.func("f", FunctionType.FUNCTION_TYPE_VOID).body(b -> {
53             b.op(CoreOp.return_());
54         });
55         funcOp.seal();
56         funcOp.seal();
57     }
58 
59     @Test
60     void test4() {
61         IntBinaryOperator q = (@Reflect IntBinaryOperator)(int a, int b) -> {
62             return a + b;
63         };
64         Quoted quoted = Op.ofQuotable(q).get();
65         CoreOp.QuotedOp quotedOp = (CoreOp.QuotedOp) quoted.op().ancestorBody().ancestorOp();
66         CoreOp.FuncOp funcOp = (CoreOp.FuncOp) quotedOp.ancestorBody().ancestorOp();
67         Assertions.assertTrue(funcOp.isSealed());
68         assertOpIsCopiedWhenAddedToBlock(funcOp);
69     }
70 
71     @Test
72     void test5() { // freezing an already bound op should throw
73         Body.Builder body = Body.Builder.of(null, FunctionType.FUNCTION_TYPE_VOID);
74         Op.Result r = body.entryBlock().op(CoreOp.constant(JavaType.DOUBLE, 1d));
75         Assertions.assertThrows(IllegalStateException.class, () -> r.op().seal());
76     }
77 
78     @Test
79     void test6() {
80         CoreOp.ConstantOp cop = CoreOp.constant(JavaType.LONG, 1L);
81         cop.setLocation(Location.NO_LOCATION);
82         cop.seal();
83         Assertions.assertThrows(IllegalStateException.class, () -> cop.setLocation(Location.NO_LOCATION));
84     }
85 
86     void assertOpIsCopiedWhenAddedToBlock(Op op) {
87         Body.Builder body = Body.Builder.of(null, FunctionType.FUNCTION_TYPE_VOID);
88         body.entryBlock().op(op);
89         body.entryBlock().op(CoreOp.return_());
90         CoreOp.FuncOp funcOp = CoreOp.func("t", body);
91         boolean b = funcOp.body().entryBlock().ops().stream().allMatch(o -> o != op);
92         Assertions.assertTrue(b);
93     }
94 }