33628
|
1 |
/*
|
|
2 |
* Copyright (c) 2015, 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 java.lang.annotation.*;
|
|
25 |
import java.lang.reflect.*;
|
|
26 |
import java.util.Arrays;
|
|
27 |
|
|
28 |
/*
|
|
29 |
* @test
|
|
30 |
* @bug 8054307
|
|
31 |
* @summary Tests correctness of string related intrinsics and C2 optimizations.
|
|
32 |
* @run main/timeout=240 TestStringIntrinsics
|
|
33 |
*/
|
|
34 |
public class TestStringIntrinsics {
|
|
35 |
|
|
36 |
public enum Operation {
|
|
37 |
ARR_EQUALS_B, ARR_EQUALS_C, EQUALS, COMPARE_TO, INDEX_OF, INDEX_OF_CON_U, INDEX_OF_CON_L,
|
|
38 |
INDEX_OF_CON_UL, CONCAT, CONCAT_C, CONCAT_I, CONCAT_M, INDEX_OF_CHAR
|
|
39 |
}
|
|
40 |
|
|
41 |
@Retention(RetentionPolicy.RUNTIME)
|
|
42 |
@Target(ElementType.METHOD)
|
|
43 |
@interface Test {
|
|
44 |
Operation op();
|
|
45 |
String constString() default "";
|
|
46 |
String[] inStrings() default {};
|
|
47 |
char[] inChars() default {};
|
|
48 |
int[] inInts() default {};
|
|
49 |
String[] outStrings() default {};
|
|
50 |
}
|
|
51 |
|
|
52 |
public static void main(String[] args) throws Exception {
|
|
53 |
new TestStringIntrinsics().run();
|
|
54 |
}
|
|
55 |
|
|
56 |
public void run() throws Exception {
|
|
57 |
// Build latin1 and UTF16 strings
|
|
58 |
StringBuilder latin1Builder = new StringBuilder();
|
|
59 |
for (int i = 0; i <= 255; ++i) {
|
|
60 |
latin1Builder.append((char) i);
|
|
61 |
}
|
|
62 |
String latin1 = latin1Builder.toString();
|
|
63 |
StringBuilder utf16Builder = new StringBuilder();
|
|
64 |
for (int i = 0; i <= 10000; ++i) {
|
|
65 |
utf16Builder.append((char) i);
|
|
66 |
}
|
|
67 |
String utf16 = utf16Builder.toString();
|
|
68 |
|
|
69 |
// Invoke test methods
|
|
70 |
for (Method m : TestStringIntrinsics.class.getMethods()) {
|
|
71 |
if (m.isAnnotationPresent(Test.class)) {
|
|
72 |
System.out.print("Checking " + m.getName() + "... ");
|
|
73 |
Operation op = m.getAnnotation(Test.class).op();
|
|
74 |
Test antn = m.getAnnotation(Test.class);
|
|
75 |
if (isStringConcatTest(op)) {
|
|
76 |
checkStringConcat(op, m, antn);
|
|
77 |
} else {
|
|
78 |
checkIntrinsics(op, m, latin1, utf16, antn);
|
|
79 |
}
|
|
80 |
System.out.println("Done.");
|
|
81 |
}
|
|
82 |
}
|
|
83 |
}
|
|
84 |
|
|
85 |
private boolean isStringConcatTest(Operation op) {
|
|
86 |
return op == Operation.CONCAT ||
|
|
87 |
op == Operation.CONCAT_C ||
|
|
88 |
op == Operation.CONCAT_I ||
|
|
89 |
op == Operation.CONCAT_M;
|
|
90 |
}
|
|
91 |
|
|
92 |
/**
|
|
93 |
* Checks correctness of the String.equals, String.compareTo and String.indexOf intrinsics.
|
|
94 |
* -XX:SpecialStringEquals
|
|
95 |
* -XX:SpecialStringCompareTo
|
|
96 |
* -XX:SpecialStringIndexOf
|
|
97 |
*/
|
|
98 |
private void checkIntrinsics(Operation op, Method m, String latin1, String utf16, Test antn) throws Exception {
|
|
99 |
for (int i = 0; i < 50_000; ++i) {
|
|
100 |
// Copy and permute latin1 and UTF16 string
|
|
101 |
char[] arrL = latin1.toCharArray();
|
|
102 |
int indexL = i % arrL.length;
|
|
103 |
int mod = (arrL.length - arrL[indexL]);
|
|
104 |
int incL = i % ((mod != 0) ? mod : 1);
|
|
105 |
arrL[indexL] = (char) ((int) arrL[indexL] + incL);
|
|
106 |
String latin1Copy = String.valueOf(arrL);
|
|
107 |
|
|
108 |
char[] arrU = utf16.toCharArray();
|
|
109 |
int indexU = i % arrU.length;
|
|
110 |
mod = (arrU.length - arrU[indexU]);
|
|
111 |
int incU = i % ((mod != 0) ? mod : 1);
|
|
112 |
arrU[indexU] = (char) ((int) arrU[indexU] + incU);
|
|
113 |
String utf16Copy = String.valueOf(arrU);
|
|
114 |
|
|
115 |
switch (op) {
|
|
116 |
case ARR_EQUALS_B:
|
|
117 |
invokeAndCheck(m, (incL == 0), latin1.getBytes("ISO-8859-1"), latin1Copy.getBytes("ISO-8859-1"));
|
|
118 |
invokeAndCheck(m, true, new byte[] {1, 2, 3}, new byte[] {1, 2, 3});
|
|
119 |
invokeAndCheck(m, true, new byte[] {1}, new byte[] {1});
|
|
120 |
invokeAndCheck(m, true, new byte[] {}, new byte[] {});
|
|
121 |
break;
|
|
122 |
case ARR_EQUALS_C:
|
|
123 |
invokeAndCheck(m, (incU == 0), utf16.toCharArray(), arrU);
|
|
124 |
break;
|
|
125 |
case EQUALS:
|
|
126 |
invokeAndCheck(m, (incL == 0), latin1, latin1Copy);
|
|
127 |
invokeAndCheck(m, false, latin1, "");
|
|
128 |
invokeAndCheck(m, false, "", latin1);
|
|
129 |
|
|
130 |
invokeAndCheck(m, (incU == 0), utf16, utf16Copy);
|
|
131 |
invokeAndCheck(m, false, utf16, "");
|
|
132 |
invokeAndCheck(m, false, "", utf16);
|
|
133 |
|
|
134 |
invokeAndCheck(m, false, latin1, utf16);
|
|
135 |
break;
|
|
136 |
case COMPARE_TO:
|
|
137 |
invokeAndCheck(m, -incL, latin1, latin1Copy);
|
|
138 |
invokeAndCheck(m, latin1.length(), latin1, "");
|
|
139 |
|
|
140 |
invokeAndCheck(m, -incU, utf16, utf16Copy);
|
|
141 |
invokeAndCheck(m, utf16.length(), utf16, "");
|
|
142 |
|
|
143 |
// Cross coder
|
|
144 |
char cL = latin1.charAt(indexL);
|
|
145 |
char cU = utf16.charAt(indexU);
|
|
146 |
invokeAndCheck(m, cL - cU, latin1, latin1.replace(cL, cU));
|
|
147 |
invokeAndCheck(m, cU - cL, utf16, utf16.replace(cU, cL));
|
|
148 |
|
|
149 |
// Different lengths
|
|
150 |
invokeAndCheck(m, 1, "ABCD", "ABC");
|
|
151 |
invokeAndCheck(m, -1, "\uff21\uff22\uff23", "\uff21\uff22\uff23\uff24");
|
|
152 |
invokeAndCheck(m, 1, "ABC\uff24", "ABC");
|
|
153 |
invokeAndCheck(m, 3, "ABC\uff24\uff25\uff26", "ABC");
|
|
154 |
invokeAndCheck(m, -1, "ABC","ABC\uff24");
|
|
155 |
invokeAndCheck(m, -3, "ABC","ABC\uff24\uff25\uff26");
|
|
156 |
break;
|
|
157 |
case INDEX_OF:
|
|
158 |
invokeAndCheck(m, indexL, latin1, latin1.substring(indexL), (indexL > 42) ? 42 : 0);
|
|
159 |
invokeAndCheck(m, 0, latin1, "", 0);
|
|
160 |
|
|
161 |
invokeAndCheck(m, indexU, utf16, utf16.substring(indexU), (indexU > 42) ? 42 : 0);
|
|
162 |
invokeAndCheck(m, 0, utf16, "", 0);
|
|
163 |
|
|
164 |
// Cross coder
|
|
165 |
invokeAndCheck(m, -1, latin1.substring(0, indexL), utf16.substring(indexU), (indexL > 42) ? 42 : 0);
|
|
166 |
// Skip latin1 chars in utf16 string
|
|
167 |
int start = 256;
|
|
168 |
int end = indexU > start ? indexU : start;
|
|
169 |
invokeAndCheck(m, end-start, utf16.substring(start, end) + latin1.substring(indexL), latin1.substring(indexL), 0);
|
|
170 |
break;
|
|
171 |
case INDEX_OF_CON_L:
|
|
172 |
invokeAndCheck(m, antn.constString(), latin1);
|
|
173 |
break;
|
|
174 |
case INDEX_OF_CON_U:
|
|
175 |
invokeAndCheck(m, antn.constString(), utf16);
|
|
176 |
break;
|
|
177 |
case INDEX_OF_CON_UL:
|
|
178 |
invokeAndCheck(m, antn.constString(), utf16);
|
|
179 |
break;
|
|
180 |
case INDEX_OF_CHAR:
|
|
181 |
invokeAndCheck(m, 7, "abcdefg\uD800\uDC00", 65536, 0);
|
|
182 |
invokeAndCheck(m, -1, "abcdefg\uD800\uDC01", 65536, 0);
|
|
183 |
invokeAndCheck(m, -1, "abcdefg\uD800", 65536, 0);
|
|
184 |
invokeAndCheck(m, 3, "abc\u0107", 263, 0);
|
|
185 |
invokeAndCheck(m, -1, "abc\u0108", 263, 0);
|
|
186 |
invokeAndCheck(m, 7, "abcdefg\u0107", 263, 0);
|
|
187 |
invokeAndCheck(m, 7, "abcdefg\u0107", 263, -1);
|
|
188 |
invokeAndCheck(m, 0, "\u0107", 263, 0);
|
|
189 |
break;
|
|
190 |
default:
|
|
191 |
throw new RuntimeException("Unexpected operation.");
|
|
192 |
}
|
|
193 |
}
|
|
194 |
}
|
|
195 |
|
|
196 |
/**
|
|
197 |
* Checks correctness of the C2 string concatenation optimization.
|
|
198 |
* -XX:OptimizeStringConcat
|
|
199 |
*/
|
|
200 |
private void checkStringConcat(Operation op, Method m, Test antn) throws Exception {
|
|
201 |
for (int i = 0; i < 50_000; ++i) {
|
|
202 |
String[] result = antn.outStrings();
|
|
203 |
switch(op) {
|
|
204 |
case CONCAT:
|
|
205 |
String[] strs = antn.inStrings();
|
|
206 |
for (int j = 0; j < strs.length; ++j) {
|
|
207 |
invokeAndCheck(m, result[j], strs[j]);
|
|
208 |
}
|
|
209 |
break;
|
|
210 |
case CONCAT_C:
|
|
211 |
char[] ch = antn.inChars();
|
|
212 |
for (int j = 0; j < ch.length; ++j) {
|
|
213 |
invokeAndCheck(m, result[j], ch[j]);
|
|
214 |
}
|
|
215 |
break;
|
|
216 |
case CONCAT_I:
|
|
217 |
int[] k = antn.inInts();
|
|
218 |
for (int j = 0; j < k.length; ++j) {
|
|
219 |
invokeAndCheck(m, result[j], k[j]);
|
|
220 |
}
|
|
221 |
break;
|
|
222 |
case CONCAT_M:
|
|
223 |
strs = antn.inStrings();
|
|
224 |
ch = antn.inChars();
|
|
225 |
k = antn.inInts();
|
|
226 |
for (int j = 0; j < strs.length; ++j) {
|
|
227 |
invokeAndCheck(m, result[j], strs[j], ch[j], k[j]);
|
|
228 |
}
|
|
229 |
break;
|
|
230 |
default:
|
|
231 |
throw new RuntimeException("Unexpected operation.");
|
|
232 |
}
|
|
233 |
}
|
|
234 |
}
|
|
235 |
|
|
236 |
/**
|
|
237 |
* Invokes method 'm' by passing arguments 'args' and checks if the
|
|
238 |
* returned value equals 'expectedResult'.
|
|
239 |
*/
|
|
240 |
private void invokeAndCheck(Method m, Object expectedResult, Object... args) throws Exception {
|
|
241 |
Object result = m.invoke(null, args);
|
|
242 |
if (!result.equals(expectedResult)) {
|
|
243 |
// System.out.println("Expected:");
|
|
244 |
// System.out.println(expectedResult);
|
|
245 |
// System.out.println("Returned:");
|
|
246 |
// System.out.println(result);
|
|
247 |
throw new RuntimeException("Result of '" + m.getName() + "' not equal to expected value.");
|
|
248 |
}
|
|
249 |
}
|
|
250 |
|
|
251 |
/*
|
|
252 |
* Constants
|
|
253 |
*/
|
|
254 |
static final char charU = '\uff21';
|
|
255 |
static final char charL = 'A';
|
|
256 |
static final String emptyString = "";
|
|
257 |
static final String stringL = "abcdefghijklmnop";
|
|
258 |
static final String stringSmallL = "abc";
|
|
259 |
static final String stringU = "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28";
|
|
260 |
static final String stringSmallU = "\u0f21\u0f22\u0f23";
|
|
261 |
static final int constInt = 123;
|
|
262 |
static final int constIntNeg = -123;
|
|
263 |
|
|
264 |
/*
|
|
265 |
* Arrays.equals
|
|
266 |
*/
|
|
267 |
@Test(op = Operation.ARR_EQUALS_B)
|
|
268 |
public static boolean arrayEqualsB(byte[] a, byte[] b) {
|
|
269 |
return Arrays.equals(a, b);
|
|
270 |
}
|
|
271 |
|
|
272 |
@Test(op = Operation.ARR_EQUALS_C)
|
|
273 |
public static boolean arrayEqualsC(char[] a, char[] b) {
|
|
274 |
return Arrays.equals(a, b);
|
|
275 |
}
|
|
276 |
|
|
277 |
/*
|
|
278 |
* String.equals
|
|
279 |
*/
|
|
280 |
@Test(op = Operation.EQUALS)
|
|
281 |
public static boolean equals(String a, String b) {
|
|
282 |
return a.equals(b);
|
|
283 |
}
|
|
284 |
|
|
285 |
/*
|
|
286 |
* String.compareTo
|
|
287 |
*/
|
|
288 |
@Test(op = Operation.COMPARE_TO)
|
|
289 |
public static int compareTo(String a, String b) {
|
|
290 |
return a.compareTo(b);
|
|
291 |
}
|
|
292 |
|
|
293 |
/*
|
|
294 |
* String.indexOf
|
|
295 |
*/
|
|
296 |
@Test(op = Operation.INDEX_OF)
|
|
297 |
public static int indexOf(String a, String b, int from) {
|
|
298 |
return a.indexOf(b, from);
|
|
299 |
}
|
|
300 |
|
|
301 |
@Test(op = Operation.INDEX_OF_CON_U, constString = stringSmallU)
|
|
302 |
public static String indexOfConstU(String a) {
|
|
303 |
int result = a.indexOf(stringSmallU);
|
|
304 |
return a.substring(result, result + stringSmallU.length());
|
|
305 |
}
|
|
306 |
|
|
307 |
@Test(op = Operation.INDEX_OF_CON_U, constString = stringU)
|
|
308 |
public static String indexOfConstLargeU(String a) {
|
|
309 |
int result = a.indexOf(stringU);
|
|
310 |
return a.substring(result, result + stringU.length());
|
|
311 |
}
|
|
312 |
|
|
313 |
@Test(op = Operation.INDEX_OF_CON_U, constString = emptyString)
|
|
314 |
public static String indexOfConstEmptyU(String a) {
|
|
315 |
int result = a.indexOf(emptyString);
|
|
316 |
return a.substring(result, result + emptyString.length());
|
|
317 |
}
|
|
318 |
|
|
319 |
@Test(op = Operation.INDEX_OF_CON_L, constString = stringSmallL)
|
|
320 |
public static String indexOfConstL(String a) {
|
|
321 |
int result = a.indexOf(stringSmallL);
|
|
322 |
return a.substring(result, result + stringSmallL.length());
|
|
323 |
}
|
|
324 |
|
|
325 |
@Test(op = Operation.INDEX_OF_CON_L, constString = stringL)
|
|
326 |
public static String indexOfConstLargeL(String a) {
|
|
327 |
int result = a.indexOf(stringL);
|
|
328 |
return a.substring(result, result + stringL.length());
|
|
329 |
}
|
|
330 |
|
|
331 |
@Test(op = Operation.INDEX_OF_CON_L, constString = emptyString)
|
|
332 |
public static String indexOfConstEmptyL(String a) {
|
|
333 |
int result = a.indexOf(emptyString);
|
|
334 |
return a.substring(result, result + emptyString.length());
|
|
335 |
}
|
|
336 |
|
|
337 |
@Test(op = Operation.INDEX_OF_CON_UL, constString = stringSmallL)
|
|
338 |
public static String indexOfConstUL(String a) {
|
|
339 |
int result = a.indexOf(stringSmallL);
|
|
340 |
return a.substring(result, result + stringSmallL.length());
|
|
341 |
}
|
|
342 |
|
|
343 |
@Test(op = Operation.INDEX_OF_CON_UL, constString = stringL)
|
|
344 |
public static String indexOfConstLargeUL(String a) {
|
|
345 |
int result = a.indexOf(stringL);
|
|
346 |
return a.substring(result, result + stringL.length());
|
|
347 |
}
|
|
348 |
|
|
349 |
@Test(op = Operation.INDEX_OF_CHAR)
|
|
350 |
public static int indexOfChar(String a, int ch, int from) {
|
|
351 |
return a.indexOf(ch, from);
|
|
352 |
}
|
|
353 |
|
|
354 |
/*
|
|
355 |
* String concatenation optimization
|
|
356 |
*/
|
|
357 |
@Test(op = Operation.CONCAT, inStrings = {"ABC", "\uff21\uff22\uff23"}, outStrings = {"ABC", "\uff21\uff22\uff23"})
|
|
358 |
public static String concatString(String a) {
|
|
359 |
return new StringBuilder().append(a).toString();
|
|
360 |
}
|
|
361 |
|
|
362 |
@Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {""})
|
|
363 |
public static String concatStringEmpty(String a) {
|
|
364 |
return new StringBuilder().toString();
|
|
365 |
}
|
|
366 |
|
|
367 |
@Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {"null"})
|
|
368 |
public static String concatStringNull(String a) {
|
|
369 |
return new StringBuilder().append((String)null).toString();
|
|
370 |
}
|
|
371 |
|
|
372 |
@Test(op = Operation.CONCAT, inStrings = {"ABC", "\uff21\uff22\uff23"}, outStrings = {"abcdefghijklmnopABCabc", "abcdefghijklmnop\uff21\uff22\uff23abc"})
|
|
373 |
public static String concatStringConstL(String a) {
|
|
374 |
return new StringBuilder().append(stringL).append(a).append(stringSmallL).toString();
|
|
375 |
}
|
|
376 |
|
|
377 |
@Test(op = Operation.CONCAT, inStrings = {"ABC", "\uff21\uff22\uff23"}, outStrings = {"\u0f21\u0f22\u0f23ABC\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28", "\u0f21\u0f22\u0f23\uff21\uff22\uff23\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28"})
|
|
378 |
public static String concatStringConstU(String a) {
|
|
379 |
return new StringBuilder().append(stringSmallU).append(a).append(stringU).toString();
|
|
380 |
}
|
|
381 |
|
|
382 |
@Test(op = Operation.CONCAT_C, inChars = {'A', '\uff21'}, outStrings = {"A", "\uff21"})
|
|
383 |
public static String concatChar(char a) {
|
|
384 |
return new StringBuilder().append(a).toString();
|
|
385 |
}
|
|
386 |
|
|
387 |
@Test(op = Operation.CONCAT_C, inChars = {'A', '\uff21'}, outStrings = {"abcdefghijklmnopAabcA\uff21", "abcdefghijklmnop\uff21abcA\uff21"})
|
|
388 |
public static String concatCharConstL(char a) {
|
|
389 |
return new StringBuilder().append(stringL).append(a).append(stringSmallL).append(charL).append(charU).toString();
|
|
390 |
}
|
|
391 |
|
|
392 |
@Test(op = Operation.CONCAT_C, inChars = {'A', '\uff21'}, outStrings = {"\u0f21\u0f22\u0f23A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21A", "\u0f21\u0f22\u0f23\uff21\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21A"})
|
|
393 |
public static String concatCharConstU(char a) {
|
|
394 |
return new StringBuilder().append(stringSmallU).append(a).append(stringU).append(charU).append(charL).toString();
|
|
395 |
}
|
|
396 |
|
|
397 |
@Test(op = Operation.CONCAT_I, inInts = {Integer.MIN_VALUE, -42, 42, Integer.MAX_VALUE}, outStrings = {"-2147483648", "-42", "42", "2147483647"})
|
|
398 |
public static String concatInt(int a) {
|
|
399 |
return new StringBuilder().append(a).toString();
|
|
400 |
}
|
|
401 |
|
|
402 |
@Test(op = Operation.CONCAT_I, inInts = {Integer.MIN_VALUE, -42, 42, Integer.MAX_VALUE}, outStrings = {"abcdefghijklmnop-2147483648abc123-123", "abcdefghijklmnop-42abc123-123", "abcdefghijklmnop42abc123-123", "abcdefghijklmnop2147483647abc123-123"})
|
|
403 |
public static String concatIntConstL(int b) {
|
|
404 |
return new StringBuilder().append(stringL).append(b).append(stringSmallL).append(constInt).append(constIntNeg).toString();
|
|
405 |
}
|
|
406 |
|
|
407 |
@Test(op = Operation.CONCAT_I, inInts = {Integer.MIN_VALUE, -42, 42, Integer.MAX_VALUE}, outStrings = {"\u0f21\u0f22\u0f23-2147483648\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123", "\u0f21\u0f22\u0f23-42\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123", "\u0f21\u0f22\u0f2342\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123", "\u0f21\u0f22\u0f232147483647\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123"})
|
|
408 |
public static String concatIntConstU(int b) {
|
|
409 |
return new StringBuilder().append(stringSmallU).append(b).append(stringU).append(constInt).append(constIntNeg).toString();
|
|
410 |
}
|
|
411 |
|
|
412 |
@Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {"nullabcabcdefghijklmnopA123-123"})
|
|
413 |
public static String concatConstL(String a) {
|
|
414 |
return new StringBuilder().append((String)null).append(stringSmallL).append(stringL).append(charL).append(constInt).append(constIntNeg).toString();
|
|
415 |
}
|
|
416 |
|
|
417 |
@Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {"nullabcabcdefghijklmnop\u0f21\u0f22\u0f23\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28A\uff21123-123"})
|
|
418 |
public static String concatConstU(String a) {
|
|
419 |
return new StringBuilder().append((String)null).append(stringSmallL).append(stringL).append(stringSmallU).append(stringU).append(charL).append(charU).append(constInt).append(constIntNeg).toString();
|
|
420 |
}
|
|
421 |
|
|
422 |
@Test(op = Operation.CONCAT_M,
|
|
423 |
inStrings = {"ABCDEFG", "ABCDEFG", "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28", "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28"},
|
|
424 |
inChars = {'A', '\uff21', 'A', '\uff21'},
|
|
425 |
inInts = {Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE},
|
|
426 |
outStrings = {"ABCDEFGA-2147483648nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21ABCDEFGA-2147483648null",
|
|
427 |
"ABCDEFG\uff212147483647nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21ABCDEFG\uff212147483647null",
|
|
428 |
"\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28A-2147483648nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28A-2147483648null",
|
|
429 |
"\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff212147483647nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff212147483647null"})
|
|
430 |
public static String concatMixed(String a, char b, int c) {
|
|
431 |
return new StringBuilder().append(a).append(b).append(c).append((String)null)
|
|
432 |
.append(stringL).append(constInt).append(constIntNeg).append(charL).append(stringU).append(charU)
|
|
433 |
.append(a).append(b).append(c).append((String)null).toString();
|
|
434 |
}
|
|
435 |
}
|