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