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 import jdk.incubator.code.extern.DialectFactory;
 25 import jdk.incubator.code.dialect.java.JavaType;
 26 import org.testng.Assert;
 27 import org.testng.annotations.Test;
 28 
 29 import java.lang.invoke.MethodHandles;
 30 import java.lang.reflect.Method;
 31 import jdk.incubator.code.Op;
 32 import jdk.incubator.code.OpTransformer;
 33 import jdk.incubator.code.analysis.SSA;
 34 import jdk.incubator.code.interpreter.Interpreter;
 35 import jdk.incubator.code.dialect.core.CoreOp;
 36 import jdk.incubator.code.dialect.java.JavaOp;
 37 import jdk.incubator.code.internal.OpBuilder;
 38 import jdk.incubator.code.CodeReflection;
 39 import java.util.Optional;
 40 import java.util.stream.Stream;
 41 
 42 /*
 43  * @test
 44  * @modules jdk.incubator.code
 45  * @modules jdk.incubator.code/jdk.incubator.code.internal
 46  * @run testng TestCodeBuilder
 47  */
 48 
 49 public class TestCodeBuilder {
 50 
 51     @CodeReflection
 52     static void constants() {
 53         boolean bool = false;
 54         byte b = 1;
 55         char c = 'a';
 56         short s = 1;
 57         int i = 1;
 58         long l = 1L;
 59         float f = 1.0f;
 60         double d = 1.0;
 61         String str = "1";
 62         Object obj = null;
 63         Class<?> klass = Object.class;
 64     }
 65 
 66     @Test
 67     public void testConstants() {
 68         testWithTransforms(getFuncOp("constants"));
 69     }
 70 
 71     static record X(int f) {
 72         void m() {}
 73     }
 74 
 75     @CodeReflection
 76     static void reflect() {
 77         X x = new X(1);
 78         int i = x.f;
 79         x.m();
 80         X[] ax = new X[1];
 81         int l = ax.length;
 82         x = ax[0];
 83 
 84         Object o = x;
 85         x = (X) o;
 86         if (o instanceof X) {
 87             return;
 88         }
 89         if (o instanceof X(var a)) {
 90             return;
 91         }
 92     }
 93 
 94     @Test
 95     public void testReflect() {
 96         testWithTransforms(getFuncOp("reflect"));
 97     }
 98 
 99     @CodeReflection
100     static int bodies(int m, int n) {
101         int sum = 0;
102         for (int i = 0; i < m; i++) {
103             for (int j = 0; j < n; j++) {
104                 sum += i + j;
105             }
106         }
107         return m > 10 ? sum : 0;
108     }
109 
110     @Test
111     public void testBodies() {
112         testWithTransforms(getFuncOp("bodies"));
113     }
114 
115     public void testWithTransforms(CoreOp.FuncOp f) {
116         test(f);
117 
118         f = f.transform(OpTransformer.LOWERING_TRANSFORMER);
119         test(f);
120 
121         f = SSA.transform(f);
122         test(f);
123     }
124 
125     static void test(CoreOp.FuncOp fExpected) {
126         CoreOp.FuncOp fb = OpBuilder.createBuilderFunction(fExpected,
127                 b -> b.parameter(JavaType.type(DialectFactory.class)));
128         CoreOp.FuncOp fActual = (CoreOp.FuncOp) Interpreter.invoke(MethodHandles.lookup(),
129                 fb, JavaOp.JAVA_DIALECT_FACTORY);
130         Assert.assertEquals(fActual.toText(), fExpected.toText());
131     }
132 
133     static CoreOp.FuncOp getFuncOp(String name) {
134         Optional<Method> om = Stream.of(TestCodeBuilder.class.getDeclaredMethods())
135                 .filter(m -> m.getName().equals(name))
136                 .findFirst();
137 
138         Method m = om.get();
139         return Op.ofMethod(m).get();
140     }
141 }