|  | // Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  | package stringconcat; | 
|  |  | 
|  | public class StringConcat { | 
|  | private static void check(String actual, String expected) { | 
|  | if (expected.equals(actual)) { | 
|  | return; | 
|  | } | 
|  | throw new AssertionError( | 
|  | "Test method failed: expected=[" + expected + "], actual=[" + actual + "]"); | 
|  | } | 
|  |  | 
|  | // --------- used 'makeConcat' signatures --------- | 
|  |  | 
|  | private static String makeConcat() { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(String s) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(char[] s) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(Object o) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(boolean o) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(char o) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(byte o) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(short o) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(int o) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(long o) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(float o) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(double o) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcat(Object o, String st, boolean z, | 
|  | char c, byte b, short s, int i, long l, float f, double d) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | // --------- used 'makeConcatWithConstants' signatures --------- | 
|  |  | 
|  | private static String makeConcatWithConstants(String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(String s, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(char[] s, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(Object o, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(boolean o, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(char o, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(byte o, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(short o, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(int o, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(long o, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(float o, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(double o, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(Object o, String st, boolean z, | 
|  | char c, byte b, short s, int i, long l, float f, double d, String recipe) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants(int i, String s, String recipe, String sConst) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | private static String makeConcatWithConstants( | 
|  | int i, String s, String recipe, String sConstA, String sConstB, String sConstC) { | 
|  | throw new AssertionError("unreachable"); | 
|  | } | 
|  |  | 
|  | // ------------------------------------------------ | 
|  |  | 
|  | private static void testEmpty() { | 
|  | check(makeConcat(), ""); | 
|  | makeConcat(); | 
|  |  | 
|  | check(makeConcatWithConstants("RECIPE:"), ""); | 
|  | check(makeConcatWithConstants("RECIPE:12-34"), "12-34"); | 
|  | makeConcatWithConstants("RECIPE:a"); | 
|  | } | 
|  |  | 
|  | private static void testSingleValueString() { | 
|  | check(makeConcat("str"), "str"); | 
|  | check(makeConcat((String) null), "null"); | 
|  |  | 
|  | check(makeConcatWithConstants("()", "RECIPE:prefix\u0001suffix"), "prefix()suffix"); | 
|  | check(makeConcatWithConstants("()", "RECIPE:prefix\u0001"), "prefix()"); | 
|  | check(makeConcatWithConstants("()", "RECIPE:\u0001suffix"), "()suffix"); | 
|  | check(makeConcatWithConstants("()", "RECIPE:\u0001"), "()"); | 
|  | } | 
|  |  | 
|  | private static void testSingleValueArray() { | 
|  | // Unchecked since Array.toString() is non-deterministic. | 
|  | makeConcat(new char[] { 'a', 'b' }); | 
|  | makeConcatWithConstants(new char[] { 'a', 'b' }, "RECIPE:prefix\u0001suffix"); | 
|  | } | 
|  |  | 
|  | private static void testSingleValueObject() { | 
|  | check(makeConcat((Object) "object"), "object"); | 
|  | check(makeConcat((Object) 1.234), "1.234"); | 
|  | check(makeConcat((Object) null), "null"); | 
|  |  | 
|  | check( | 
|  | makeConcatWithConstants((Object) "object", "RECIPE:prefix\u0001suffix"), | 
|  | "prefixobjectsuffix"); | 
|  | check( | 
|  | makeConcatWithConstants((Object) 1.234, "RECIPE:prefix\u0001suffix"), | 
|  | "prefix1.234suffix"); | 
|  | check( | 
|  | makeConcatWithConstants((Object) null, "RECIPE:prefix\u0001suffix"), | 
|  | "prefixnullsuffix"); | 
|  | } | 
|  |  | 
|  | private static void testSingleValuePrimitive() { | 
|  | check(makeConcat(true), "true"); | 
|  | check(makeConcat((char) 65), "A"); | 
|  | check(makeConcat((byte) 1), "1"); | 
|  | check(makeConcat((short) 2), "2"); | 
|  | check(makeConcat(3), "3"); | 
|  | check(makeConcat((long) 4), "4"); | 
|  | check(makeConcat((float) 5), "5.0"); | 
|  | check(makeConcat((double) 6), "6.0"); | 
|  |  | 
|  | check(makeConcatWithConstants(true, "RECIPE:prefix\u0001suffix"), "prefixtruesuffix"); | 
|  | check(makeConcatWithConstants((char) 65, "RECIPE:prefix\u0001suffix"), "prefixAsuffix"); | 
|  | check(makeConcatWithConstants((byte) 1, "RECIPE:prefix\u0001suffix"), "prefix1suffix"); | 
|  | check(makeConcatWithConstants((short) 2, "RECIPE:prefix\u0001suffix"), "prefix2suffix"); | 
|  | check(makeConcatWithConstants(3, "RECIPE:prefix\u0001suffix"), "prefix3suffix"); | 
|  | check(makeConcatWithConstants((long) 4, "RECIPE:prefix\u0001suffix"), "prefix4suffix"); | 
|  | check(makeConcatWithConstants((float) 5, "RECIPE:prefix\u0001suffix"), "prefix5.0suffix"); | 
|  | check(makeConcatWithConstants((double) 6, "RECIPE:prefix\u0001suffix"), "prefix6.0suffix"); | 
|  | } | 
|  |  | 
|  | private static void testAllTypes(Object o, String st, boolean z, | 
|  | char c, byte b, short s, int i, long l, float f, double d) { | 
|  | check(makeConcat(o, st, z, c, b, s, i, l, f, d), "nullstrtrueA12345.06.0"); | 
|  | check(makeConcatWithConstants(o, st, z, c, b, s, i, l, f, d, | 
|  | "RECIPE:[\u0001-\u0001>\u0001===\u0001\u0001\u0001alpha\u0001beta\u0001\u0001]\u0001"), | 
|  | "[null-str>true===A12alpha3beta45.0]6.0"); | 
|  | } | 
|  |  | 
|  | private static void testInExceptionContext(Object o, String st, boolean z, | 
|  | char c, byte b, short s, int i, long l, float f, double d) { | 
|  | check(makeConcat((long) 4), "4"); | 
|  | try { | 
|  | check(makeConcat(o, st, z, c, b, s, i, l, f, d), "nullstrtrueA12345.06.0"); | 
|  | check(makeConcatWithConstants(o, st, z, c, b, s, i, l, f, d, | 
|  | "RECIPE:\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"), | 
|  | "nullstrtrueA12345.06.0"); | 
|  | try { | 
|  | check(makeConcat("try-try"), "try-try"); | 
|  | throw new IndexOutOfBoundsException(); | 
|  | } catch (NullPointerException re) { | 
|  | throw new AssertionError("UNREACHABLE"); | 
|  | } catch (Exception re) { | 
|  | check(makeConcatWithConstants(o, st, z, c, b, s, i, l, f, d, | 
|  | "RECIPE:(\u0001, \u0001, \u0001, \u0001, \u0001, " | 
|  | + "\u0001, \u0001, \u0001, \u0001, \u0001)"), | 
|  | "(null, str, true, A, 1, 2, 3, 4, 5.0, 6.0)"); | 
|  | throw new IndexOutOfBoundsException(); | 
|  | } | 
|  | } catch (IndexOutOfBoundsException re) { | 
|  | check(makeConcat("bar"), "bar"); | 
|  | check(makeConcatWithConstants("foo", "RECIPE:bar -> \u0001"), "bar -> foo"); | 
|  | try { | 
|  | check(makeConcatWithConstants("inside", "RECIPE:try \u0001 try"), "try inside try"); | 
|  | throw new NullPointerException(); | 
|  | } catch (IndexOutOfBoundsException e) { | 
|  | throw new AssertionError("UNREACHABLE"); | 
|  | } catch (NullPointerException npe) { | 
|  | check(makeConcat(o, st, z, c, b, s, i, l, f, d), "nullstrtrueA12345.06.0"); | 
|  | } | 
|  | } catch (Exception re) { | 
|  | throw new AssertionError("UNREACHABLE"); | 
|  | } | 
|  | } | 
|  |  | 
|  | private static void testConcatWitConstants() { | 
|  | check( | 
|  | makeConcatWithConstants( | 
|  | 123, "abc", "RECIPE:arg=\u0001; const=\u0002; arg=\u0001", "str" | 
|  | ), | 
|  | "arg=123; const=str; arg=abc"); | 
|  | check( | 
|  | makeConcatWithConstants( | 
|  | 123, "abc", "RECIPE:\u0002arg=\u0001\u0002arg=\u0001\u0002", | 
|  | "prefix-", "-infix-", "-suffix" | 
|  | ), | 
|  | "prefix-arg=123-infix-arg=abc-suffix"); | 
|  | } | 
|  |  | 
|  | // ------------------------------------------------ | 
|  |  | 
|  | public static void main(String[] args) { | 
|  | testEmpty(); | 
|  | testSingleValueString(); | 
|  | testSingleValueArray(); | 
|  | testSingleValueObject(); | 
|  | testSingleValuePrimitive(); | 
|  | testAllTypes(null, "str", true, (char) 65, | 
|  | (byte) 1, (short) 2, 3, (long) 4, (float) 5, (double) 6); | 
|  | testInExceptionContext(null, "str", true, (char) 65, | 
|  | (byte) 1, (short) 2, 3, (long) 4, (float) 5, (double) 6); | 
|  | testConcatWitConstants(); | 
|  | } | 
|  | } |