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