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 }