Denis Vnukov | e443431 | 2017-10-12 12:45:50 -0700 | [diff] [blame] | 1 | // Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file |
| 2 | // for details. All rights reserved. Use of this source code is governed by a |
| 3 | // BSD-style license that can be found in the LICENSE file. |
| 4 | package stringconcat; |
| 5 | |
| 6 | public class StringConcat { |
| 7 | private static void check(String actual, String expected) { |
| 8 | if (expected.equals(actual)) { |
| 9 | return; |
| 10 | } |
| 11 | throw new AssertionError( |
| 12 | "Test method failed: expected=[" + expected + "], actual=[" + actual + "]"); |
| 13 | } |
| 14 | |
| 15 | // --------- used 'makeConcat' signatures --------- |
| 16 | |
| 17 | private static String makeConcat() { |
| 18 | throw new AssertionError("unreachable"); |
| 19 | } |
| 20 | |
| 21 | private static String makeConcat(String s) { |
| 22 | throw new AssertionError("unreachable"); |
| 23 | } |
| 24 | |
| 25 | private static String makeConcat(char[] s) { |
| 26 | throw new AssertionError("unreachable"); |
| 27 | } |
| 28 | |
| 29 | private static String makeConcat(Object o) { |
| 30 | throw new AssertionError("unreachable"); |
| 31 | } |
| 32 | |
| 33 | private static String makeConcat(boolean o) { |
| 34 | throw new AssertionError("unreachable"); |
| 35 | } |
| 36 | |
| 37 | private static String makeConcat(char o) { |
| 38 | throw new AssertionError("unreachable"); |
| 39 | } |
| 40 | |
| 41 | private static String makeConcat(byte o) { |
| 42 | throw new AssertionError("unreachable"); |
| 43 | } |
| 44 | |
| 45 | private static String makeConcat(short o) { |
| 46 | throw new AssertionError("unreachable"); |
| 47 | } |
| 48 | |
| 49 | private static String makeConcat(int o) { |
| 50 | throw new AssertionError("unreachable"); |
| 51 | } |
| 52 | |
| 53 | private static String makeConcat(long o) { |
| 54 | throw new AssertionError("unreachable"); |
| 55 | } |
| 56 | |
| 57 | private static String makeConcat(float o) { |
| 58 | throw new AssertionError("unreachable"); |
| 59 | } |
| 60 | |
| 61 | private static String makeConcat(double o) { |
| 62 | throw new AssertionError("unreachable"); |
| 63 | } |
| 64 | |
| 65 | private static String makeConcat(Object o, String st, boolean z, |
| 66 | char c, byte b, short s, int i, long l, float f, double d) { |
| 67 | throw new AssertionError("unreachable"); |
| 68 | } |
| 69 | |
| 70 | // --------- used 'makeConcatWithConstants' signatures --------- |
| 71 | |
| 72 | private static String makeConcatWithConstants(String recipe) { |
| 73 | throw new AssertionError("unreachable"); |
| 74 | } |
| 75 | |
| 76 | private static String makeConcatWithConstants(String s, String recipe) { |
| 77 | throw new AssertionError("unreachable"); |
| 78 | } |
| 79 | |
| 80 | private static String makeConcatWithConstants(char[] s, String recipe) { |
| 81 | throw new AssertionError("unreachable"); |
| 82 | } |
| 83 | |
| 84 | private static String makeConcatWithConstants(Object o, String recipe) { |
| 85 | throw new AssertionError("unreachable"); |
| 86 | } |
| 87 | |
| 88 | private static String makeConcatWithConstants(boolean o, String recipe) { |
| 89 | throw new AssertionError("unreachable"); |
| 90 | } |
| 91 | |
| 92 | private static String makeConcatWithConstants(char o, String recipe) { |
| 93 | throw new AssertionError("unreachable"); |
| 94 | } |
| 95 | |
| 96 | private static String makeConcatWithConstants(byte o, String recipe) { |
| 97 | throw new AssertionError("unreachable"); |
| 98 | } |
| 99 | |
| 100 | private static String makeConcatWithConstants(short o, String recipe) { |
| 101 | throw new AssertionError("unreachable"); |
| 102 | } |
| 103 | |
| 104 | private static String makeConcatWithConstants(int o, String recipe) { |
| 105 | throw new AssertionError("unreachable"); |
| 106 | } |
| 107 | |
| 108 | private static String makeConcatWithConstants(long o, String recipe) { |
| 109 | throw new AssertionError("unreachable"); |
| 110 | } |
| 111 | |
| 112 | private static String makeConcatWithConstants(float o, String recipe) { |
| 113 | throw new AssertionError("unreachable"); |
| 114 | } |
| 115 | |
| 116 | private static String makeConcatWithConstants(double o, String recipe) { |
| 117 | throw new AssertionError("unreachable"); |
| 118 | } |
| 119 | |
| 120 | private static String makeConcatWithConstants(Object o, String st, boolean z, |
| 121 | char c, byte b, short s, int i, long l, float f, double d, String recipe) { |
| 122 | throw new AssertionError("unreachable"); |
| 123 | } |
| 124 | |
| 125 | private static String makeConcatWithConstants(int i, String s, String recipe, String sConst) { |
| 126 | throw new AssertionError("unreachable"); |
| 127 | } |
| 128 | |
| 129 | private static String makeConcatWithConstants( |
| 130 | int i, String s, String recipe, String sConstA, String sConstB, String sConstC) { |
| 131 | throw new AssertionError("unreachable"); |
| 132 | } |
| 133 | |
| 134 | // ------------------------------------------------ |
| 135 | |
| 136 | private static void testEmpty() { |
| 137 | check(makeConcat(), ""); |
| 138 | makeConcat(); |
| 139 | |
| 140 | check(makeConcatWithConstants("RECIPE:"), ""); |
| 141 | check(makeConcatWithConstants("RECIPE:12-34"), "12-34"); |
| 142 | makeConcatWithConstants("RECIPE:a"); |
| 143 | } |
| 144 | |
| 145 | private static void testSingleValueString() { |
| 146 | check(makeConcat("str"), "str"); |
| 147 | check(makeConcat((String) null), "null"); |
| 148 | |
| 149 | check(makeConcatWithConstants("()", "RECIPE:prefix\u0001suffix"), "prefix()suffix"); |
| 150 | check(makeConcatWithConstants("()", "RECIPE:prefix\u0001"), "prefix()"); |
| 151 | check(makeConcatWithConstants("()", "RECIPE:\u0001suffix"), "()suffix"); |
| 152 | check(makeConcatWithConstants("()", "RECIPE:\u0001"), "()"); |
| 153 | } |
| 154 | |
| 155 | private static void testSingleValueArray() { |
| 156 | // Unchecked since Array.toString() is non-deterministic. |
| 157 | makeConcat(new char[] { 'a', 'b' }); |
| 158 | makeConcatWithConstants(new char[] { 'a', 'b' }, "RECIPE:prefix\u0001suffix"); |
| 159 | } |
| 160 | |
| 161 | private static void testSingleValueObject() { |
| 162 | check(makeConcat((Object) "object"), "object"); |
| 163 | check(makeConcat((Object) 1.234), "1.234"); |
| 164 | check(makeConcat((Object) null), "null"); |
| 165 | |
| 166 | check( |
| 167 | makeConcatWithConstants((Object) "object", "RECIPE:prefix\u0001suffix"), |
| 168 | "prefixobjectsuffix"); |
| 169 | check( |
| 170 | makeConcatWithConstants((Object) 1.234, "RECIPE:prefix\u0001suffix"), |
| 171 | "prefix1.234suffix"); |
| 172 | check( |
| 173 | makeConcatWithConstants((Object) null, "RECIPE:prefix\u0001suffix"), |
| 174 | "prefixnullsuffix"); |
| 175 | } |
| 176 | |
| 177 | private static void testSingleValuePrimitive() { |
| 178 | check(makeConcat(true), "true"); |
| 179 | check(makeConcat((char) 65), "A"); |
| 180 | check(makeConcat((byte) 1), "1"); |
| 181 | check(makeConcat((short) 2), "2"); |
| 182 | check(makeConcat(3), "3"); |
| 183 | check(makeConcat((long) 4), "4"); |
| 184 | check(makeConcat((float) 5), "5.0"); |
| 185 | check(makeConcat((double) 6), "6.0"); |
| 186 | |
| 187 | check(makeConcatWithConstants(true, "RECIPE:prefix\u0001suffix"), "prefixtruesuffix"); |
| 188 | check(makeConcatWithConstants((char) 65, "RECIPE:prefix\u0001suffix"), "prefixAsuffix"); |
| 189 | check(makeConcatWithConstants((byte) 1, "RECIPE:prefix\u0001suffix"), "prefix1suffix"); |
| 190 | check(makeConcatWithConstants((short) 2, "RECIPE:prefix\u0001suffix"), "prefix2suffix"); |
| 191 | check(makeConcatWithConstants(3, "RECIPE:prefix\u0001suffix"), "prefix3suffix"); |
| 192 | check(makeConcatWithConstants((long) 4, "RECIPE:prefix\u0001suffix"), "prefix4suffix"); |
| 193 | check(makeConcatWithConstants((float) 5, "RECIPE:prefix\u0001suffix"), "prefix5.0suffix"); |
| 194 | check(makeConcatWithConstants((double) 6, "RECIPE:prefix\u0001suffix"), "prefix6.0suffix"); |
| 195 | } |
| 196 | |
| 197 | private static void testAllTypes(Object o, String st, boolean z, |
| 198 | char c, byte b, short s, int i, long l, float f, double d) { |
| 199 | check(makeConcat(o, st, z, c, b, s, i, l, f, d), "nullstrtrueA12345.06.0"); |
| 200 | check(makeConcatWithConstants(o, st, z, c, b, s, i, l, f, d, |
| 201 | "RECIPE:[\u0001-\u0001>\u0001===\u0001\u0001\u0001alpha\u0001beta\u0001\u0001]\u0001"), |
| 202 | "[null-str>true===A12alpha3beta45.0]6.0"); |
| 203 | } |
| 204 | |
| 205 | private static void testInExceptionContext(Object o, String st, boolean z, |
| 206 | char c, byte b, short s, int i, long l, float f, double d) { |
| 207 | check(makeConcat((long) 4), "4"); |
| 208 | try { |
| 209 | check(makeConcat(o, st, z, c, b, s, i, l, f, d), "nullstrtrueA12345.06.0"); |
| 210 | check(makeConcatWithConstants(o, st, z, c, b, s, i, l, f, d, |
| 211 | "RECIPE:\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"), |
| 212 | "nullstrtrueA12345.06.0"); |
| 213 | try { |
| 214 | check(makeConcat("try-try"), "try-try"); |
| 215 | throw new IndexOutOfBoundsException(); |
| 216 | } catch (NullPointerException re) { |
| 217 | throw new AssertionError("UNREACHABLE"); |
| 218 | } catch (Exception re) { |
| 219 | check(makeConcatWithConstants(o, st, z, c, b, s, i, l, f, d, |
| 220 | "RECIPE:(\u0001, \u0001, \u0001, \u0001, \u0001, " |
| 221 | + "\u0001, \u0001, \u0001, \u0001, \u0001)"), |
| 222 | "(null, str, true, A, 1, 2, 3, 4, 5.0, 6.0)"); |
| 223 | throw new IndexOutOfBoundsException(); |
| 224 | } |
| 225 | } catch (IndexOutOfBoundsException re) { |
| 226 | check(makeConcat("bar"), "bar"); |
| 227 | check(makeConcatWithConstants("foo", "RECIPE:bar -> \u0001"), "bar -> foo"); |
| 228 | try { |
| 229 | check(makeConcatWithConstants("inside", "RECIPE:try \u0001 try"), "try inside try"); |
| 230 | throw new NullPointerException(); |
| 231 | } catch (IndexOutOfBoundsException e) { |
| 232 | throw new AssertionError("UNREACHABLE"); |
| 233 | } catch (NullPointerException npe) { |
| 234 | check(makeConcat(o, st, z, c, b, s, i, l, f, d), "nullstrtrueA12345.06.0"); |
| 235 | } |
| 236 | } catch (Exception re) { |
| 237 | throw new AssertionError("UNREACHABLE"); |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | private static void testConcatWitConstants() { |
| 242 | check( |
| 243 | makeConcatWithConstants( |
| 244 | 123, "abc", "RECIPE:arg=\u0001; const=\u0002; arg=\u0001", "str" |
| 245 | ), |
| 246 | "arg=123; const=str; arg=abc"); |
| 247 | check( |
| 248 | makeConcatWithConstants( |
| 249 | 123, "abc", "RECIPE:\u0002arg=\u0001\u0002arg=\u0001\u0002", |
| 250 | "prefix-", "-infix-", "-suffix" |
| 251 | ), |
| 252 | "prefix-arg=123-infix-arg=abc-suffix"); |
| 253 | } |
| 254 | |
| 255 | // ------------------------------------------------ |
| 256 | |
| 257 | public static void main(String[] args) { |
| 258 | testEmpty(); |
| 259 | testSingleValueString(); |
| 260 | testSingleValueArray(); |
| 261 | testSingleValueObject(); |
| 262 | testSingleValuePrimitive(); |
| 263 | testAllTypes(null, "str", true, (char) 65, |
| 264 | (byte) 1, (short) 2, 3, (long) 4, (float) 5, (double) 6); |
| 265 | testInExceptionContext(null, "str", true, (char) 65, |
| 266 | (byte) 1, (short) 2, 3, (long) 4, (float) 5, (double) 6); |
| 267 | testConcatWitConstants(); |
| 268 | } |
| 269 | } |