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 TestBuildOp
19 */
20 public class TestBuildOp {
21
22 @Reflect
23 static List<Integer> f(int i) {
24 return new ArrayList<>(i);
25 }
26
27 @Test
28 void testCopyFromMethod() throws NoSuchMethodException {
29 Method m = this.getClass().getDeclaredMethod("f", int.class);
30 CoreOp.FuncOp f = Op.ofMethod(m).get();
31
32 assertOpIsCopiedWhenAddedToBlock(f);
33 }
34
35 @Test
36 void testCopyFromLambda() {
37 IntUnaryOperator q = (@Reflect IntUnaryOperator) i -> i / 2;
38 Quoted<?> quoted = Op.ofLambda(q).get();
39 assert quoted.capturedValues().isEmpty();
40
41 assertOpIsCopiedWhenAddedToBlock(quoted.op());
42 }
43
44 @Test
45 void testCopyFromOp() {
46 CoreOp.ConstantOp constant = CoreOp.constant(JavaType.INT, 7);
47 constant.buildAsRoot();
48
49 assertOpIsCopiedWhenAddedToBlock(constant);
50 }
51
52 @Test
53 void testBuildAsRoot() {
54 CoreOp.FuncOp funcOp = CoreOp.func("f", FunctionType.FUNCTION_TYPE_VOID).body(b -> {
55 b.op(CoreOp.return_());
56 });
57
58 Assertions.assertFalse(funcOp.isRoot());
59 Assertions.assertFalse(funcOp.isBound());
60 funcOp.buildAsRoot();
61
62 Assertions.assertTrue(funcOp.isRoot());
63 Assertions.assertFalse(funcOp.isBound());
64 funcOp.buildAsRoot();
65 }
66
67 @Test
68 void testBuiltLambdaRoot() {
69 IntBinaryOperator q = (@Reflect IntBinaryOperator)(int a, int b) -> a + b;
70 Quoted<?> quoted = Op.ofLambda(q).orElseThrow();
71
72 CoreOp.QuotedOp quotedOp = (CoreOp.QuotedOp) quoted.op().ancestorOp();
73 CoreOp.FuncOp funcOp = (CoreOp.FuncOp) quotedOp.ancestorOp();
74
75 Assertions.assertTrue(funcOp.isRoot());
76 Assertions.assertFalse(funcOp.isBound());
77 }
78
79 @Test
80 void testOpBound() {
81 Body.Builder body = Body.Builder.of(null, FunctionType.FUNCTION_TYPE_VOID);
82 Op.Result r = body.entryBlock().op(CoreOp.constant(JavaType.DOUBLE, 1d));
83 body.entryBlock().op(CoreOp.return_());
84
85 Assertions.assertThrows(IllegalStateException.class, () -> r.op().buildAsRoot());
86 Assertions.assertTrue(r.op().isBound());
87 Assertions.assertFalse(r.op().isRoot());
88
89 CoreOp.func("f", body);
90 Assertions.assertTrue(r.op().isBound());
91 }
92
93 @Test
94 void testSetLocation() {
95 CoreOp.ConstantOp cop = CoreOp.constant(JavaType.LONG, 1L);
96 cop.setLocation(Op.Location.NO_LOCATION);
97 cop.buildAsRoot();
98
99 Assertions.assertThrows(IllegalStateException.class, () -> cop.setLocation(Op.Location.NO_LOCATION));
100
101 IntBinaryOperator q = (@Reflect IntBinaryOperator)(int a, int b) -> a + b;
102 Quoted<?> quoted = Op.ofLambda(q).orElseThrow();
103 Assertions.assertThrows(IllegalStateException.class, () -> quoted.op().setLocation(Op.Location.NO_LOCATION));
104 }
105
106 void assertOpIsCopiedWhenAddedToBlock(Op op) {
107 Body.Builder body = Body.Builder.of(null, FunctionType.FUNCTION_TYPE_VOID);
108 body.entryBlock().op(op);
109 body.entryBlock().op(CoreOp.return_());
110 CoreOp.FuncOp funcOp = CoreOp.func("t", body);
111 boolean b = funcOp.body().entryBlock().ops().stream().allMatch(o -> o != op);
112 Assertions.assertTrue(b);
113 }
114 }