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 import java.io.IOException;
  25 import java.io.PrintWriter;
  26 import java.nio.file.Files;
  27 import java.nio.file.Paths;
  28 import java.util.*;
  29 
  30 public class ImplicitStringConcatShapesTestGen {
  31     public static String escapeToUnicode(String str) {
  32         StringBuilder b = new StringBuilder();
  33         for (char c : str.toCharArray()) {
  34             if (c < 128) {
  35                 b.append(c);
  36             } else {
  37                 b.append("\\u").append(String.format("%04X", (int) c));
  38             }
  39         }
  40         return b.toString();
  41     }
  42 
  43     public static void main(String... args) throws IOException {
  44         PrintWriter pw = new PrintWriter(System.out);
  45 
  46         String[] types = {
  47                 "boolean",
  48                 "byte",
  49                 "byteMinus",
  50                 "char",
  51                 "short",
  52                 "shortMinus",
  53                 "int",
  54                 "intMinus",
  55                 "integer",
  56                 "integerNull",
  57                 "float",
  58                 "floatMinus",
  59                 "long",
  60                 "longMinus",
  61                 "double",
  62                 "doubleMinus",
  63                 "object",
  64                 "objectNull",
  65                 "objectNullToString",
  66                 "String",
  67                 "StringUTF16",
  68                 "StringU1",
  69                 "StringU2",
  70                 "intArrayNull",
  71                 "objectArrayNull",
  72         };
  73 
  74         for (String t : Files.readAllLines(Paths.get("ImplicitStringConcatShapes-head.template"))) {
  75             pw.println(t);
  76         }
  77 
  78         Map<String, String> values = new HashMap<>();
  79 
  80         Random current = new Random(12345);
  81         for (int mode = 0; mode <= 2; mode++) {
  82             for (String type : types) {
  83                 int i = current.nextInt(100);
  84                 boolean isStatic = (mode | 1) == 1;
  85                 boolean isFinal = (mode | 2) == 2;
  86                 String fieldName = (isStatic ? "s" : "") + (isFinal ? "f" : "") + "_" + typeSig(type);
  87                 String value = initValue(type, i);
  88                 String stringValue = stringValue(type, i);
  89                 values.put(fieldName, stringValue);
  90                 pw.printf("    %s %s %s %s = %s;%n", isStatic ? "static" : "", isFinal ? "final" : "", typeValue(type, i), fieldName, value);
  91             }
  92         }
  93 
  94         pw.println();
  95 
  96         List<String> lines = new ArrayList<>();
  97         List<String> l = new ArrayList<>(values.keySet());
  98 
  99         for (String l1 : l) {
 100             lines.add(String.format("test(\"%s\", \"\" + %s);",
 101                     escapeToUnicode(values.get(l1)),
 102                     l1
 103             ));
 104         }
 105 
 106         for (String l1 : l) {
 107             for (String l2 : l) {
 108                 lines.add(String.format("test(\"%s\", \"\" + %s + %s);",
 109                         escapeToUnicode(values.get(l1) + values.get(l2)),
 110                         l1, l2
 111                 ));
 112             }
 113         }
 114 
 115         final int STRIDE = 1000;
 116         int strides = lines.size() / STRIDE + 1;
 117 
 118         pw.println("    public void run() {");
 119         for (int c = 0; c < strides; c++) {
 120             pw.println("        run" + c + "();");
 121         }
 122         pw.println("    }");
 123         pw.println();
 124 
 125         for (int c = 0; c < strides; c++) {
 126             pw.println("    public void run" + c + "() {");
 127             for (String line : lines.subList(c * STRIDE, Math.min(lines.size(), (c+1) * STRIDE))) {
 128                 pw.println("        " + line);
 129             }
 130             pw.println("    }");
 131             pw.println();
 132         }
 133 
 134         pw.println("}");
 135 
 136         pw.flush();
 137         pw.close();
 138     }
 139 
 140     private static String typeSig(String type) {
 141         switch (type) {
 142             case "boolean":             return "bl";
 143             case "byte":                return "b";
 144             case "byteMinus":           return "bM";
 145             case "short":               return "s";
 146             case "shortMinus":          return "sM";
 147             case "char":                return "c";
 148             case "int":                 return "i";
 149             case "intMinus":            return "iM";
 150             case "integer":             return "I";
 151             case "integerNull":         return "IN";
 152             case "float":               return "f";
 153             case "floatMinus":          return "fM";
 154             case "long":                return "l";
 155             case "longMinus":           return "lM";
 156             case "double":              return "d";
 157             case "doubleMinus":         return "dM";
 158             case "String":              return "str";
 159             case "StringUTF16":         return "strU";
 160             case "StringU1":            return "strU1";
 161             case "StringU2":            return "strU2";
 162             case "object":              return "o";
 163             case "objectNull":          return "oN";
 164             case "objectNullToString":  return "oNtS";
 165             case "intArrayNull":        return "iAN";
 166             case "objectArrayNull":     return "oAN";
 167             default:
 168                 throw new IllegalStateException();
 169         }
 170     }
 171 
 172     private static String typeValue(String type, int i) {
 173         switch (type) {
 174             case "boolean":
 175             case "byte":
 176             case "byteMinus":
 177             case "char":
 178             case "short":
 179             case "shortMinus":
 180             case "int":
 181             case "intMinus":
 182             case "float":
 183             case "floatMinus":
 184             case "long":
 185             case "longMinus":
 186             case "double":
 187             case "doubleMinus":
 188                 return type.replace("Minus", "");
 189             case "String":
 190             case "StringUTF16":
 191             case "StringU1":
 192             case "StringU2":
 193                 return "String";
 194             case "object":
 195             case "objectNull":
 196             case "objectNullToString":
 197                 return "Object";
 198             case "integer":
 199             case "integerNull":
 200                 return "Integer";
 201             case "intArrayNull":
 202                 return "int[]";
 203             case "objectArrayNull":
 204                 return "Object[]";
 205             default:
 206                 throw new IllegalStateException();
 207         }
 208     }
 209 
 210     private static String initValue(String type, int i) {
 211         switch (type) {
 212             case "boolean":
 213                 return String.valueOf((i & 1) == 1);
 214             case "byte":
 215                 return String.valueOf(i);
 216             case "byteMinus":
 217                 return String.valueOf(-i);
 218             case "short":
 219                 return String.valueOf(i*100);
 220             case "shortMinus":
 221                 return String.valueOf(-i*100);
 222             case "intMinus":
 223                 return String.valueOf(-i*1_000_000);
 224             case "int":
 225             case "integer":
 226                 return String.valueOf(i*1_000_000);
 227             case "long":
 228                 return String.valueOf(i*1_000_000_000) + "L";
 229             case "longMinus":
 230                 return String.valueOf(-i*1_000_000_000) + "L";
 231             case "char":
 232                 return "'" + (char)(i % 26 + 65) + "'";
 233             case "double":
 234                 return String.valueOf(i) + ".0d";
 235             case "doubleMinus":
 236                 return "-" + String.valueOf(i) + ".0d";
 237             case "float":
 238                 return String.valueOf(i) + ".0f";
 239             case "floatMinus":
 240                 return "-" + String.valueOf(i) + ".0f";
 241             case "object":
 242                 return "new MyClass(" + i + ")";
 243             case "objectNullToString":
 244                 return "new MyClassNullToString()";
 245             case "integerNull":
 246             case "objectNull":
 247             case "intArrayNull":
 248             case "objectArrayNull":
 249                 return "null";
 250             case "String":
 251                 return "\"" + i + "\"";
 252             case "StringUTF16":
 253                 return "\"\\u0451" + i + "\"";
 254             case "StringU1":
 255                 return "\"\\u0001" + i + "\"";
 256             case "StringU2":
 257                 return "\"\\u0002" + i + "\"";
 258             default:
 259                 throw new IllegalStateException();
 260         }
 261     }
 262 
 263     private static String stringValue(String type, int i) {
 264         switch (type) {
 265             case "boolean":
 266                 return String.valueOf((i & 1) == 1);
 267             case "byte":
 268                 return String.valueOf(i);
 269             case "byteMinus":
 270                 return String.valueOf(-i);
 271             case "short":
 272                 return String.valueOf(i*100);
 273             case "shortMinus":
 274                 return String.valueOf(-i*100);
 275             case "intMinus":
 276                 return String.valueOf(-i*1_000_000);
 277             case "int":
 278             case "integer":
 279                 return String.valueOf(i*1_000_000);
 280             case "long":
 281                 return String.valueOf(i*1_000_000_000);
 282             case "longMinus":
 283                 return String.valueOf(-i*1_000_000_000);
 284             case "char":
 285                 return String.valueOf((char) (i % 26 + 65));
 286             case "double":
 287             case "float":
 288                 return String.valueOf(i) + ".0";
 289             case "doubleMinus":
 290             case "floatMinus":
 291                 return "-" + String.valueOf(i) + ".0";
 292             case "object":
 293                 return "C(" + i + ")";
 294             case "integerNull":
 295             case "objectNull":
 296             case "objectNullToString":
 297             case "intArrayNull":
 298             case "objectArrayNull":
 299                 return "null";
 300             case "String":
 301                 return "" + i;
 302             case "StringUTF16":
 303                 return "\u0451" + i;
 304             case "StringU1":
 305                 return "\u0001" + i;
 306             case "StringU2":
 307                 return "\u0002" + i;
 308             default:
 309                 throw new IllegalStateException();
 310         }
 311     }
 312 
 313 }