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();
 120     static {
 121         sb.append('a');
 122     }
 123 
 124     public static void main(String[] args) throws Exception {
 125 
 126         test("footrue", s + b);
 127         test("foo42",   s + by);
 128         test("foo42",   s + sh);
 129         test("fooa",    s + ch);
 130         test("foo42",   s + i);
 131         test("foo42",   s + l);
 132         test("foo42.0", s + fl);
 133         test("foo42.0", s + d);
 134         test("foofoo",  s + s);
 135         test("foonull", s + sNull);
 136         test("foobar",  s + o);
 137         test("foonull", s + oNull);
 138         test("foobar",  s + cs);
 139 
 140         {
 141             StringBuilder sb = new StringBuilder();
 142             sb.append("foo");
 143             sb.append(myArr.toString());
 144             test(sb.toString(), s + myArr);
 145         }
 146 
 147         {
 148             StringBuilder sb = new StringBuilder();
 149             sb.append("foo");
 150             sb.append(s_myArr.toString());
 151             test(sb.toString(), s + s_myArr);
 152         }
 153 
 154         {
 155             StringBuilder sb = new StringBuilder();
 156             sb.append("foo[C@");
 157             sb.append(Integer.toHexString(System.identityHashCode(chars)));
 158             test(sb.toString(), s + chars);
 159         }
 160 
 161         test("fooa",    s + ImplicitStringConcat.sb);
 162         test("foonull", s + null);
 163         test("fooMyClass", s + myCl);
 164         test("foonull",    s + myClNull);
 165         test("fooMyClass", s + myCl2);
 166 
 167         s = "foo";  s += b;     test("footrue", s);
 168         s = "foo";  s += by;    test("foo42", s);
 169         s = "foo";  s += sh;    test("foo42", s);
 170         s = "foo";  s += ch;    test("fooa", s);
 171         s = "foo";  s += i;     test("foo42", s);
 172         s = "foo";  s += l;     test("foo42", s);
 173         s = "foo";  s += fl;    test("foo42.0", s);
 174         s = "foo";  s += d;     test("foo42.0", s);
 175         s = "foo";  s += s;     test("foofoo", s);
 176         s = "foo";  s += sNull; test("foonull", s);
 177         s = "foo";  s += o;     test("foobar", s);
 178         s = "foo";  s += oNull; test("foonull", s);
 179         s = "foo";  s += cs;    test("foobar", s);
 180 
 181         {
 182             StringBuilder sb = new StringBuilder();
 183             sb.append("foo[C@");
 184             sb.append(Integer.toHexString(System.identityHashCode(chars)));
 185             s = "foo";
 186             s += chars;
 187             test(sb.toString(), s);
 188         }
 189 
 190         s = "foo";  s += ImplicitStringConcat.sb;    test("fooa", s);
 191         s = "foo";  s += null;  test("foonull", s);
 192         s = "foo";  s += myCl;  test("fooMyClass", s);
 193         s = "foo";  s += myCl2; test("fooMyClass", s);
 194     }
 195 
 196     public static void test(String expected, String actual) {
 197        // Fingers crossed: String concat should work.
 198        if (!expected.equals(actual)) {
 199            StringBuilder sb = new StringBuilder();
 200            sb.append("Expected = ");
 201            sb.append(expected);
 202            sb.append(", actual = ");
 203            sb.append(actual);
 204            throw new IllegalStateException(sb.toString());
 205        }
 206     }
 207 
 208     static class MyClass {
 209         public String toString() {
 210             return "MyClass";
 211         }
 212     }
 213 
 214     static class MyClassNull {
 215         public String toString() {
 216             return null;
 217         }
 218     }
 219 }