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.CodeReflection;
25 import jdk.incubator.code.Op;
26 import jdk.incubator.code.dialect.core.CoreOp;
27 import jdk.incubator.code.interpreter.Interpreter;
28 import org.junit.jupiter.api.Assertions;
29 import org.junit.jupiter.params.ParameterizedTest;
30 import org.junit.jupiter.params.provider.MethodSource;
31
32 import java.lang.invoke.MethodHandles;
33 import java.lang.reflect.InvocationTargetException;
34 import java.lang.reflect.Method;
35 import java.util.HashMap;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.stream.Stream;
39
40 /*
41 * @test
42 * @modules jdk.incubator.code
43 * @run junit TestConcat
44 */
45
46 public class TestConcat {
47
48 static final String TESTSTR = "TESTING STRING";
49
50 @CodeReflection
51 static String f() {
52 int test = 1;
53 String res = "HI " + TESTSTR + test;
54 return res;
55 }
56
57
58 @CodeReflection
59 public static String byteConcat1(byte b, String s) {
60 return b + s;
61 }
62
63 @CodeReflection
64 public static String byteConcat2(String s, byte b) {
65 return s + b;
66 }
67
68 @CodeReflection
69 public static String shortConcat1(short b, String s) {
70 return b + s;
71 }
72
73 @CodeReflection
74 public static String shortConcat2(String s, short b) {
75 return s + b;
76 }
77
78 @CodeReflection
79 public static String intConcat1(int b, String s) {
80 return b + s;
81 }
82
83 @CodeReflection
84 public static String intConcat2(String s, int b) {
85 return s + b;
86 }
87
88 @CodeReflection
89 public static String longConcat1(long b, String s) {
90 return b + s;
91 }
92
93 @CodeReflection
94 public static String longConcat2(String s, long b) {
95 return s + b;
96 }
97
98 @CodeReflection
99 public static String floatConcat1(float b, String s) {
100 return b + s;
101 }
102
103 @CodeReflection
104 public static String floatConcat2(String s, float b) {
105 return s + b;
106 }
107
108 @CodeReflection
109 public static String doubleConcat1(double b, String s) {
110 return b + s;
111 }
112
113 @CodeReflection
114 public static String doubleConcat2(String s, double b) {
115 return s + b;
116 }
117
118 @CodeReflection
119 public static String booleanConcat1(boolean b, String s) {
120 return b + s;
121 }
122
123 @CodeReflection
124 public static String booleanConcat2(String s, boolean b) {
125 return s + b;
126 }
127
128 @CodeReflection
129 public static String charConcat1(char b, String s) {
130 return b + s;
131 }
132 @CodeReflection
133 public static String charConcat2(String s, char b) {
134 return s + b;
135 }
136 @CodeReflection
137 public static String objectConcat1(Object b, String s) {
138 return b + s;
139 }
140
141 @CodeReflection
142 public static String objectConcat2(String s, Object b) {
143 return s + b;
144 }
145
146 @CodeReflection
147 public static String objectConcat3(TestObject b, String s) {
148 return b + s;
149 }
150
151 @CodeReflection
152 public static String objectConcat4(String s, TestObject b) {
153 return s + b;
154 }
155
156 @CodeReflection
157 public static String stringConcat(String b, String s) {
158 return b + s;
159 }
160
161
162 record TestMethodData(Class<?> first, Class<?> second, String third) {
163 }
164
165 static final Map<Class<?>, Object> valMap;
166 static {
167 valMap = new HashMap<>();
168 valMap.put(byte.class, (byte) 42);
169 valMap.put(short.class, (short) 42);
170 valMap.put(int.class, 42);
171 valMap.put(long.class, (long) 42);
172 valMap.put(float.class, 42f);
173 valMap.put(double.class, 42d);
174 valMap.put(char.class, 'z');
175 valMap.put(boolean.class, false);
176 valMap.put(Object.class, new Object() {
177 @Override
178 public String toString() {
179 return "I'm a test string.";
180 }
181 });
182 valMap.put(TestObject.class, new TestObject());
183 valMap.put(String.class, TESTSTR);
184 }
185 private static String testName(Class<?> n, Integer i){
186 return n.getSimpleName().toLowerCase() + "Concat" + i;
187 }
188
189 public static Stream<TestMethodData> testData() {
190 Set<Class<?>> types = Set.of(byte.class, short.class, int.class, long.class, float.class,
191 double.class, char.class, boolean.class, Object.class);
192
193 //Types from types concatenated to strings left-to-right and right-to-left
194 Stream<TestMethodData> s1 = types.stream().map(t -> new TestMethodData(t, String.class, testName(t, 1)));
195 Stream<TestMethodData> s2 = types.stream().map(t -> new TestMethodData(String.class, t, testName(t, 2)));
196
197 //Custom Object and basic string concat tests
198 Stream<TestMethodData> s3 = Stream.of(new TestMethodData(TestObject.class, String.class, testName(Object.class, 3)),
199 new TestMethodData(String.class, TestObject.class, testName(Object.class, 4)),
200 new TestMethodData(String.class, String.class, "stringConcat"));
201
202 return Stream.concat(Stream.concat(s1,s2),s3);
203 }
204
205 @ParameterizedTest
206 @MethodSource("testData")
207 public static void testRun(TestMethodData t) {
208 try {
209 Object[] args = new Object[] {valMap.get(t.first), valMap.get(t.second)};
210 Class<TestConcat> clazz = TestConcat.class;
211 Method method = clazz.getDeclaredMethod(t.third, t.first, t.second);
212 CoreOp.FuncOp f = Op.ofMethod(method).orElseThrow();
213 var res1 = Interpreter.invoke(MethodHandles.lookup(), f, args);
214 var res2 = method.invoke(null, args);
215
216 Assertions.assertEquals(res2, res1);
217
218 } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
219 throw new RuntimeException(e);
220 }
221 }
222
223 public static final class TestObject {
224 TestObject(){}
225
226 @Override
227 public String toString() {
228 return "TestObject String";
229 }
230 }
231 }