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 }