< prev index next >

test/java/lang/String/concat/StringConcatFactoryInvariants.java

Print this page
rev 17632 : 8186500: StringConcatFactory.makeConcatWithConstants throws AssertionError when recipe contains non-String constants
Reviewed-by: shade, psandoz


  53  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  54  *
  55  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  56  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  57  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  58  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  59  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  60  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  61  *
  62 */
  63 public class StringConcatFactoryInvariants {
  64 
  65     private static final char TAG_ARG   = '\u0001';
  66     private static final char TAG_CONST = '\u0002';
  67 
  68     public static void main(String[] args) throws Throwable {
  69         MethodHandles.Lookup lookup = MethodHandles.lookup();
  70         String methodName = "foo";
  71         MethodType mt = MethodType.methodType(String.class, String.class, int.class);
  72         String recipe = "" + TAG_ARG + TAG_ARG + TAG_CONST;
  73         String[] constants = new String[]{"bar"};


























  74 
  75         final int LIMIT = 200;
  76 
  77         // Simple factory: check for dynamic arguments overflow
  78         Class<?>[] underThreshold = new Class<?>[LIMIT - 1];
  79         Class<?>[] threshold      = new Class<?>[LIMIT];
  80         Class<?>[] overThreshold  = new Class<?>[LIMIT + 1];
  81 
  82         StringBuilder sbUnderThreshold = new StringBuilder();
  83         sbUnderThreshold.append(TAG_CONST);
  84         for (int c = 0; c < LIMIT - 1; c++) {
  85             underThreshold[c] = int.class;
  86             threshold[c] = int.class;
  87             overThreshold[c] = int.class;
  88             sbUnderThreshold.append(TAG_ARG);
  89         }
  90         threshold[LIMIT - 1] = int.class;
  91         overThreshold[LIMIT - 1] = int.class;
  92         overThreshold[LIMIT] = int.class;
  93 
  94         String recipeEmpty = "";
  95         String recipeUnderThreshold = sbUnderThreshold.toString();
  96         String recipeThreshold = sbUnderThreshold.append(TAG_ARG).toString();
  97         String recipeOverThreshold = sbUnderThreshold.append(TAG_ARG).toString();
  98 
  99         MethodType mtEmpty = MethodType.methodType(String.class);
 100         MethodType mtUnderThreshold = MethodType.methodType(String.class, underThreshold);
 101         MethodType mtThreshold = MethodType.methodType(String.class, threshold);
 102         MethodType mtOverThreshold = MethodType.methodType(String.class, overThreshold);
 103 
 104 
 105         // Check the basic functionality is working
 106         {
 107             CallSite cs = StringConcatFactory.makeConcat(lookup, methodName, mt);
 108             test("foo42", (String) cs.getTarget().invokeExact("foo", 42));
 109         }
 110 
 111         {
 112             CallSite cs = StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, recipe, constants);
 113             test("foo42bar", (String) cs.getTarget().invokeExact("foo", 42));


 114         }
 115 
 116         // Simple factory, check for nulls:
 117         failNPE("Lookup is null",
 118                 () -> StringConcatFactory.makeConcat(null, methodName, mt));
 119 
 120         failNPE("Method name is null",
 121                 () -> StringConcatFactory.makeConcat(lookup, null, mt));
 122 
 123         failNPE("MethodType is null",
 124                 () -> StringConcatFactory.makeConcat(lookup, methodName, null));
 125 
 126         // Advanced factory, check for nulls:



 127         failNPE("Lookup is null",
 128                 () -> StringConcatFactory.makeConcatWithConstants(null, methodName, mt, recipe, constants));
 129 
 130         failNPE("Method name is null",
 131                 () -> StringConcatFactory.makeConcatWithConstants(lookup, null, mt, recipe, constants));
 132 
 133         failNPE("MethodType is null",
 134                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, null, recipe, constants));
 135 
 136         failNPE("Recipe is null",
 137                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, null, constants));

 138 
 139         failNPE("Constants vararg is null",
 140                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, recipe, null));



 141 
 142         // Simple factory, check for return type
 143         fail("Return type: void",
 144                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(void.class, String.class, int.class)));
 145 
 146         fail("Return type: int",
 147                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(int.class, String.class, int.class)));
 148 
 149         fail("Return type: StringBuilder",
 150                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(StringBuilder.class, String.class, int.class)));
 151 
 152         ok("Return type: Object",
 153                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(Object.class, String.class, int.class)));
 154 
 155         ok("Return type: CharSequence",
 156                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(CharSequence.class, String.class, int.class)));
 157 
 158         ok("Return type: Serializable",
 159                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(Serializable.class, String.class, int.class)));
 160 
 161         // Advanced factory, check for return types


 162         fail("Return type: void",
 163                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(void.class, String.class, int.class), recipe, constants));
 164 
 165         fail("Return type: int",
 166                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(int.class, String.class, int.class), recipe, constants));
 167 
 168         fail("Return type: StringBuilder",
 169                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(StringBuilder.class, String.class, int.class), recipe, constants));
 170 
 171         ok("Return type: Object",
 172                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(Object.class, String.class, int.class), recipe, constants));
 173 
 174         ok("Return type: CharSequence",
 175                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(CharSequence.class, String.class, int.class), recipe, constants));
 176 
 177         ok("Return type: Serializable",
 178                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(Serializable.class, String.class, int.class), recipe, constants));

 179 
 180         // Simple factory: check for dynamic arguments overflow
 181         ok("Dynamic arguments is under limit",
 182                 () -> StringConcatFactory.makeConcat(lookup, methodName, mtUnderThreshold));
 183 
 184         ok("Dynamic arguments is at the limit",
 185                 () -> StringConcatFactory.makeConcat(lookup, methodName, mtThreshold));
 186 
 187         fail("Dynamic arguments is over the limit",
 188                 () -> StringConcatFactory.makeConcat(lookup, methodName, mtOverThreshold));
 189 
 190         // Advanced factory: check for dynamic arguments overflow
 191         ok("Dynamic arguments is under limit",
 192                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtUnderThreshold, recipeUnderThreshold, constants));
 193 
 194         ok("Dynamic arguments is at the limit",
 195                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, constants));
 196 
 197         fail("Dynamic arguments is over the limit",
 198                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtOverThreshold, recipeOverThreshold, constants));
 199 
 200         // Advanced factory: check for mismatched recipe and Constants
 201         ok("Static arguments and recipe match",
 202                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar"));
 203 
 204         fail("Static arguments and recipe mismatch",
 205                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar", "baz"));
 206 
 207         // Advanced factory: check for mismatched recipe and dynamic arguments
 208         fail("Dynamic arguments and recipe mismatch",
 209                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeUnderThreshold, constants));
 210 
 211         ok("Dynamic arguments and recipe match",
 212                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, constants));
 213 
 214         fail("Dynamic arguments and recipe mismatch",
 215                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeOverThreshold, constants));
 216 
 217         // Test passing array as constant
 218         {
 219             String[] arg = {"boo", "bar"};
 220 
 221             CallSite cs1 = StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST + TAG_CONST, arg);
 222             test("42boobar", (String) cs1.getTarget().invokeExact(42));
 223         }
 224 
 225         // Test passing null constant
 226         ok("Can pass regular constants",
 227                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST, "foo"));
 228 
 229         failNPE("Cannot pass null constants",
 230                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST, new String[]{null}));
 231 
 232         // Simple factory: test empty arguments
 233         ok("Ok to pass empty arguments",
 234                 () -> StringConcatFactory.makeConcat(lookup, methodName, mtEmpty));
 235 
 236         // Advanced factory: test empty arguments
 237         ok("Ok to pass empty arguments",
 238                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtEmpty, recipeEmpty));
 239 
 240         // Simple factory: public Lookup is rejected
 241         fail("Passing public Lookup",
 242                 () -> StringConcatFactory.makeConcat(MethodHandles.publicLookup(), methodName, mtEmpty));
 243 
 244         // Advanced factory: public Lookup is rejected
 245         fail("Passing public Lookup",
 246                 () -> StringConcatFactory.makeConcatWithConstants(MethodHandles.publicLookup(), methodName, mtEmpty, recipeEmpty));
 247     }
 248 
 249     public static void ok(String msg, Callable runnable) {
 250         try {




  53  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  54  *
  55  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  56  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  57  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  58  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  59  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  60  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
  61  *
  62 */
  63 public class StringConcatFactoryInvariants {
  64 
  65     private static final char TAG_ARG   = '\u0001';
  66     private static final char TAG_CONST = '\u0002';
  67 
  68     public static void main(String[] args) throws Throwable {
  69         MethodHandles.Lookup lookup = MethodHandles.lookup();
  70         String methodName = "foo";
  71         MethodType mt = MethodType.methodType(String.class, String.class, int.class);
  72         String recipe = "" + TAG_ARG + TAG_ARG + TAG_CONST;
  73         Object[][] constants = new Object[][] {
  74                 new String[] { "bar" },
  75                 new Integer[] { 1 },
  76                 new Short[] { 2 },
  77                 new Long[] { 3L },
  78                 new Boolean[] { true },
  79                 new Character[] { 'a' },
  80                 new Byte[] { -128 },
  81                 new Class[] { String.class },
  82                 new MethodHandle[] { MethodHandles.constant(String.class, "constant") },
  83                 new MethodType[] { MethodType.methodType(String.class) }
  84         };
  85         // The string representation that should end up if the corresponding
  86         // Object[] in constants is used as an argument to makeConcatWithConstants
  87         String[] constantString = new String[] {
  88                 "bar",
  89                 "1",
  90                 "2",
  91                 "3",
  92                 "true",
  93                 "a",
  94                 "-128",
  95                 "class java.lang.String",
  96                 "MethodHandle()String",
  97                 "()String"
  98         };
  99 
 100 
 101         final int LIMIT = 200;
 102 
 103         // Simple factory: check for dynamic arguments overflow
 104         Class<?>[] underThreshold = new Class<?>[LIMIT - 1];
 105         Class<?>[] threshold      = new Class<?>[LIMIT];
 106         Class<?>[] overThreshold  = new Class<?>[LIMIT + 1];
 107 
 108         StringBuilder sbUnderThreshold = new StringBuilder();
 109         sbUnderThreshold.append(TAG_CONST);
 110         for (int c = 0; c < LIMIT - 1; c++) {
 111             underThreshold[c] = int.class;
 112             threshold[c] = int.class;
 113             overThreshold[c] = int.class;
 114             sbUnderThreshold.append(TAG_ARG);
 115         }
 116         threshold[LIMIT - 1] = int.class;
 117         overThreshold[LIMIT - 1] = int.class;
 118         overThreshold[LIMIT] = int.class;
 119 
 120         String recipeEmpty = "";
 121         String recipeUnderThreshold = sbUnderThreshold.toString();
 122         String recipeThreshold = sbUnderThreshold.append(TAG_ARG).toString();
 123         String recipeOverThreshold = sbUnderThreshold.append(TAG_ARG).toString();
 124 
 125         MethodType mtEmpty = MethodType.methodType(String.class);
 126         MethodType mtUnderThreshold = MethodType.methodType(String.class, underThreshold);
 127         MethodType mtThreshold = MethodType.methodType(String.class, threshold);
 128         MethodType mtOverThreshold = MethodType.methodType(String.class, overThreshold);
 129 
 130 
 131         // Check the basic functionality is working
 132         {
 133             CallSite cs = StringConcatFactory.makeConcat(lookup, methodName, mt);
 134             test("foo42", (String) cs.getTarget().invokeExact("foo", 42));
 135         }
 136 
 137         {
 138             for (int i = 0; i < constants.length; i++) {
 139                 CallSite cs = StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, recipe, constants[i]);
 140                 test("foo42".concat(constantString[i]), (String) cs.getTarget().invokeExact("foo", 42));
 141             }
 142         }
 143 
 144         // Simple factory, check for nulls:
 145         failNPE("Lookup is null",
 146                 () -> StringConcatFactory.makeConcat(null, methodName, mt));
 147 
 148         failNPE("Method name is null",
 149                 () -> StringConcatFactory.makeConcat(lookup, null, mt));
 150 
 151         failNPE("MethodType is null",
 152                 () -> StringConcatFactory.makeConcat(lookup, methodName, null));
 153 
 154         // Advanced factory, check for nulls:
 155         for (int i = 0; i < constants.length; i++) {
 156             final Object[] consts = constants[i];
 157 
 158             failNPE("Lookup is null",
 159                     () -> StringConcatFactory.makeConcatWithConstants(null, methodName, mt, recipe, consts));
 160 
 161             failNPE("Method name is null",
 162                     () -> StringConcatFactory.makeConcatWithConstants(lookup, null, mt, recipe, consts));
 163 
 164             failNPE("MethodType is null",
 165                     () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, null, recipe, consts));
 166 
 167             failNPE("Recipe is null",
 168                     () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, null, consts));
 169         }
 170 
 171         failNPE("Constants vararg is null",
 172                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, recipe, (Object[]) null));
 173 
 174         failNPE("Constant argument is null",
 175                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, recipe, new Object[] { null }));
 176 
 177         // Simple factory, check for return type
 178         fail("Return type: void",
 179                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(void.class, String.class, int.class)));
 180 
 181         fail("Return type: int",
 182                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(int.class, String.class, int.class)));
 183 
 184         fail("Return type: StringBuilder",
 185                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(StringBuilder.class, String.class, int.class)));
 186 
 187         ok("Return type: Object",
 188                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(Object.class, String.class, int.class)));
 189 
 190         ok("Return type: CharSequence",
 191                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(CharSequence.class, String.class, int.class)));
 192 
 193         ok("Return type: Serializable",
 194                 () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(Serializable.class, String.class, int.class)));
 195 
 196         // Advanced factory, check for return types
 197         for (int i = 0; i < constants.length; i++) {
 198             final Object[] consts = constants[i];
 199             fail("Return type: void",
 200                     () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(void.class, String.class, int.class), recipe, consts));
 201 
 202             fail("Return type: int",
 203                     () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(int.class, String.class, int.class), recipe, consts));
 204 
 205             fail("Return type: StringBuilder",
 206                     () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(StringBuilder.class, String.class, int.class), recipe, consts));
 207 
 208             ok("Return type: Object",
 209                     () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(Object.class, String.class, int.class), recipe, consts));
 210 
 211             ok("Return type: CharSequence",
 212                     () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(CharSequence.class, String.class, int.class), recipe, consts));
 213 
 214             ok("Return type: Serializable",
 215                     () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(Serializable.class, String.class, int.class), recipe, consts));
 216         }
 217 
 218         // Simple factory: check for dynamic arguments overflow
 219         ok("Dynamic arguments is under limit",
 220                 () -> StringConcatFactory.makeConcat(lookup, methodName, mtUnderThreshold));
 221 
 222         ok("Dynamic arguments is at the limit",
 223                 () -> StringConcatFactory.makeConcat(lookup, methodName, mtThreshold));
 224 
 225         fail("Dynamic arguments is over the limit",
 226                 () -> StringConcatFactory.makeConcat(lookup, methodName, mtOverThreshold));
 227 
 228         // Advanced factory: check for dynamic arguments overflow
 229         ok("Dynamic arguments is under limit",
 230                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtUnderThreshold, recipeUnderThreshold, constants[0]));
 231 
 232         ok("Dynamic arguments is at the limit",
 233                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, constants[0]));
 234 
 235         fail("Dynamic arguments is over the limit",
 236                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtOverThreshold, recipeOverThreshold, constants[0]));
 237 
 238         // Advanced factory: check for mismatched recipe and Constants
 239         ok("Static arguments and recipe match",
 240                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar"));
 241 
 242         fail("Static arguments and recipe mismatch",
 243                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar", "baz"));
 244 
 245         // Advanced factory: check for mismatched recipe and dynamic arguments
 246         fail("Dynamic arguments and recipe mismatch",
 247                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeUnderThreshold, constants[0]));
 248 
 249         ok("Dynamic arguments and recipe match",
 250                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, constants[0]));
 251 
 252         fail("Dynamic arguments and recipe mismatch",
 253                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeOverThreshold, constants[0]));
 254 
 255         // Test passing array as constant
 256         {
 257             Object[] arg = {"boo", "bar"};
 258 
 259             CallSite cs1 = StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST + TAG_CONST, arg);
 260             test("42boobar", (String) cs1.getTarget().invokeExact(42));
 261         }
 262 
 263         // Test passing null constant
 264         ok("Can pass regular constants",
 265                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST, "foo"));
 266 
 267         failNPE("Cannot pass null constants",
 268                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST, new Object[]{null}));
 269 
 270         // Simple factory: test empty arguments
 271         ok("Ok to pass empty arguments",
 272                 () -> StringConcatFactory.makeConcat(lookup, methodName, mtEmpty));
 273 
 274         // Advanced factory: test empty arguments
 275         ok("Ok to pass empty arguments",
 276                 () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtEmpty, recipeEmpty));
 277 
 278         // Simple factory: public Lookup is rejected
 279         fail("Passing public Lookup",
 280                 () -> StringConcatFactory.makeConcat(MethodHandles.publicLookup(), methodName, mtEmpty));
 281 
 282         // Advanced factory: public Lookup is rejected
 283         fail("Passing public Lookup",
 284                 () -> StringConcatFactory.makeConcatWithConstants(MethodHandles.publicLookup(), methodName, mtEmpty, recipeEmpty));
 285     }
 286 
 287     public static void ok(String msg, Callable runnable) {
 288         try {


< prev index next >