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 junit TestConstants
 28  */
 29 
 30 import jdk.incubator.code.CodeReflection;
 31 import jdk.incubator.code.Op;
 32 import jdk.incubator.code.OpTransformer;
 33 import jdk.incubator.code.dialect.core.CoreOp;
 34 import jdk.incubator.code.interpreter.Interpreter;
 35 import org.junit.jupiter.api.Assertions;
 36 import org.junit.jupiter.api.Test;
 37 import org.junit.jupiter.params.ParameterizedTest;
 38 import org.junit.jupiter.params.provider.MethodSource;
 39 
 40 import java.lang.invoke.MethodHandles;
 41 import java.lang.reflect.Method;
 42 import java.util.List;
 43 import java.util.Optional;
 44 import java.util.stream.Stream;
 45 
 46 public class TestConstants {
 47 
 48     @CodeReflection
 49     public static boolean c_boolean() {
 50         return true;
 51     }
 52 
 53     @CodeReflection
 54     public static boolean c_boolean_f() {
 55         return false;
 56     }
 57 
 58     @CodeReflection
 59     public static byte c_byte() {
 60         return 42;
 61     }
 62 
 63     @CodeReflection
 64     public static byte c_byte_neg() {
 65         return -42;
 66     }
 67 
 68     @CodeReflection
 69     public static short c_short() {
 70         return 42;
 71     }
 72 
 73     @CodeReflection
 74     public static short c_short_neg() {
 75         return -42;
 76     }
 77 
 78     @CodeReflection
 79     public static char c_char() {
 80         return 'A';
 81     }
 82 
 83     @CodeReflection
 84     public static int c_int() {
 85         return 42;
 86     }
 87 
 88     @CodeReflection
 89     public static int c_int_neg() {
 90         return -42;
 91     }
 92 
 93     @CodeReflection
 94     public static long c_long() {
 95         return 42L;
 96     }
 97 
 98     @CodeReflection
 99     public static long c_long_neg() {
100         return -42L;
101     }
102 
103     @CodeReflection
104     public static float c_float() {
105         return 1.0f;
106     }
107 
108     @CodeReflection
109     public static float c_float_neg() {
110         return -1.0f;
111     }
112 
113     @CodeReflection
114     public static double c_double() {
115         return 1.0;
116     }
117 
118     @CodeReflection
119     public static double c_double_neg() {
120         return -1.0;
121     }
122 
123     @CodeReflection
124     public static String c_String() {
125         String s = "42";
126         s = null;
127         return s;
128     }
129 
130     @CodeReflection
131     public static Class<?> c_Class() {
132         return String.class;
133     }
134 
135     @CodeReflection
136     public static Class<?> c_Class_primitive() {
137         return float.class;
138     }
139 
140     static Object[][] provider() {
141         return new Object[][] {
142                 { boolean.class },
143                 { byte.class },
144                 { short.class },
145                 { char.class },
146                 { int.class },
147                 { long.class },
148                 { float.class },
149                 { double.class },
150                 { String.class },
151                 { Class.class }
152         };
153     }
154 
155     @ParameterizedTest
156     @MethodSource("provider")
157     public void testString(Class<?> c) throws Exception {
158         String name = "c_" + c.getSimpleName();
159         List<Method> ms = Stream.of(TestConstants.class.getDeclaredMethods())
160                 .filter(m -> m.getName().startsWith(name))
161                 .toList();
162 
163         for (Method m : ms) {
164             CoreOp.FuncOp f = Op.ofMethod(m).get();
165 
166             System.out.println(f.toText());
167 
168             Assertions.assertEquals(m.invoke(null), Interpreter.invoke(MethodHandles.lookup(), f));
169         }
170     }
171 
172     @CodeReflection
173     public static String compareNull(String s) {
174         if (s == null) {
175             return "NULL";
176         } else {
177             return s;
178         }
179     }
180 
181     @Test
182     public void testCompareNull() {
183         CoreOp.FuncOp f = getFuncOp("compareNull");
184 
185         System.out.println(f.toText());
186 
187         CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER);
188 
189         System.out.println(lf.toText());
190 
191         Assertions.assertEquals(compareNull(null), Interpreter.invoke(MethodHandles.lookup(), lf, (Object) null));
192     }
193 
194     static CoreOp.FuncOp getFuncOp(String name) {
195         Optional<Method> om = Stream.of(TestConstants.class.getDeclaredMethods())
196                 .filter(m -> m.getName().equals(name))
197                 .findFirst();
198 
199         Method m = om.get();
200         return Op.ofMethod(m).get();
201     }
202 }