1 /*
   2  * Copyright (c) 2015, 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 /**
  25  * @test
  26  * @summary test implicit String concatenations
  27  *
  28  * @compile ImplicitStringConcat.java
  29  * @run main/othervm ImplicitStringConcat
  30  *
  31  * @compile -XDstringConcat=inline ImplicitStringConcat.java
  32  * @run main/othervm ImplicitStringConcat
  33  *
  34  * @compile -XDstringConcat=indy -source 1.9 -target 1.9 ImplicitStringConcat.java
  35  *
  36  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcat
  37  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcat
  38  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcat
  39  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcat
  40  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcat
  41  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcat
  42  *
  43  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  44  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  45  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  46  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  47  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  48  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  49  *
  50  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  51  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  52  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  53  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  54  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  55  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  56 
  57  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  58  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  59  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  60  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  61  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  62  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  63  *
  64  * @compile -XDstringConcat=indyWithConstants -source 1.9 -target 1.9 ImplicitStringConcat.java
  65  *
  66  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcat
  67  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcat
  68  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcat
  69  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcat
  70  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcat
  71  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcat
  72  *
  73  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  74  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  75  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  76  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  77  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  78  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
  79  *
  80  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  81  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  82  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  83  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  84  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  85  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  86  *
  87  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  88  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  89  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  90  * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  91  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  92  * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
  93 */
  94 import java.lang.StringBuilder;
  95 
  96 public class ImplicitStringConcat {
  97 
  98     static boolean b = true;
  99     static byte by = 42;
 100     static short sh = 42;
 101     static char ch = 'a';
 102     static int i = 42;
 103     static float fl = 42.0f;
 104     static long l = 42;
 105     static double d = 42.0d;
 106     static String s = "foo";
 107     static String sNull = null;
 108     static Object o = "bar";
 109     static Object oNull = null;
 110     static CharSequence cs = "bar";
 111     static char[] chars = new char[] {'a'};
 112 
 113     static MyClass myCl = new MyClass();
 114     static MyClassNull myClNull = new MyClassNull();
 115     static Object  myCl2 = new MyClass();
 116     static Object[] myArr = new Object[] { myCl };
 117     static final Object[] s_myArr = new Object[] { myCl };
 118 
 119     static StringBuffer sb = new StringBuffer("a");
 120 
 121     public static void main(String[] args) throws Exception {
 122 
 123         test("footrue", s + b);
 124         test("foo42",   s + by);
 125         test("foo42",   s + sh);
 126         test("fooa",    s + ch);
 127         test("foo42",   s + i);
 128         test("foo42",   s + l);
 129         test("foo42.0", s + fl);
 130         test("foo42.0", s + d);
 131         test("foofoo",  s + s);
 132         test("foonull", s + sNull);
 133         test("foobar",  s + o);
 134         test("foonull", s + oNull);
 135         test("foobar",  s + cs);
 136 
 137         {
 138             StringBuilder sb = new StringBuilder();
 139             sb.append("foo");
 140             sb.append(myArr.toString());
 141             test(sb.toString(), s + myArr);
 142         }
 143 
 144         {
 145             StringBuilder sb = new StringBuilder();
 146             sb.append("foo");
 147             sb.append(s_myArr.toString());
 148             test(sb.toString(), s + s_myArr);
 149         }
 150 
 151         {
 152             StringBuilder sb = new StringBuilder();
 153             sb.append("foo[C@");
 154             sb.append(Integer.toHexString(System.identityHashCode(chars)));
 155             test(sb.toString(), s + chars);
 156         }
 157 
 158         test("fooa",    s + ImplicitStringConcat.sb);
 159         test("foonull", s + null);
 160         test("fooMyClass", s + myCl);
 161         test("foonull",    s + myClNull);
 162         test("fooMyClass", s + myCl2);
 163 
 164         s = "foo";  s += b;     test("footrue", s);
 165         s = "foo";  s += by;    test("foo42", s);
 166         s = "foo";  s += sh;    test("foo42", s);
 167         s = "foo";  s += ch;    test("fooa", s);
 168         s = "foo";  s += i;     test("foo42", s);
 169         s = "foo";  s += l;     test("foo42", s);
 170         s = "foo";  s += fl;    test("foo42.0", s);
 171         s = "foo";  s += d;     test("foo42.0", s);
 172         s = "foo";  s += s;     test("foofoo", s);
 173         s = "foo";  s += sNull; test("foonull", s);
 174         s = "foo";  s += o;     test("foobar", s);
 175         s = "foo";  s += oNull; test("foonull", s);
 176         s = "foo";  s += cs;    test("foobar", s);
 177 
 178         {
 179             StringBuilder sb = new StringBuilder();
 180             sb.append("foo[C@");
 181             sb.append(Integer.toHexString(System.identityHashCode(chars)));
 182             s = "foo";
 183             s += chars;
 184             test(sb.toString(), s);
 185         }
 186 
 187         s = "foo";  s += ImplicitStringConcat.sb;    test("fooa", s);
 188         s = "foo";  s += null;  test("foonull", s);
 189         s = "foo";  s += myCl;  test("fooMyClass", s);
 190         s = "foo";  s += myCl2; test("fooMyClass", s);
 191     }
 192 
 193     public static void test(String expected, String actual) {
 194        // Fingers crossed: String concat should work.
 195        if (!expected.equals(actual)) {
 196            StringBuilder sb = new StringBuilder();
 197            sb.append("Expected = ");
 198            sb.append(expected);
 199            sb.append(", actual = ");
 200            sb.append(actual);
 201            throw new IllegalStateException(sb.toString());
 202        }
 203     }
 204 
 205     static class MyClass {
 206         public String toString() {
 207             return "MyClass";
 208         }
 209     }
 210 
 211     static class MyClassNull {
 212         public String toString() {
 213             return null;
 214         }
 215     }
 216 }