FreshValueGenerator.java revision 0888a09821a98ac0680fad765217302858e70fa4
1/*
2 * Copyright (C) 2012 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.testing;
18
19import static com.google.common.base.Preconditions.checkNotNull;
20
21import com.google.common.base.CharMatcher;
22import com.google.common.base.Charsets;
23import com.google.common.base.Equivalence;
24import com.google.common.base.Joiner;
25import com.google.common.base.Optional;
26import com.google.common.base.Splitter;
27import com.google.common.base.Throwables;
28import com.google.common.base.Ticker;
29import com.google.common.collect.ArrayListMultimap;
30import com.google.common.collect.BiMap;
31import com.google.common.collect.HashBasedTable;
32import com.google.common.collect.HashBiMap;
33import com.google.common.collect.HashMultimap;
34import com.google.common.collect.HashMultiset;
35import com.google.common.collect.ImmutableBiMap;
36import com.google.common.collect.ImmutableCollection;
37import com.google.common.collect.ImmutableList;
38import com.google.common.collect.ImmutableListMultimap;
39import com.google.common.collect.ImmutableMap;
40import com.google.common.collect.ImmutableMultimap;
41import com.google.common.collect.ImmutableMultiset;
42import com.google.common.collect.ImmutableSet;
43import com.google.common.collect.ImmutableSetMultimap;
44import com.google.common.collect.ImmutableSortedMap;
45import com.google.common.collect.ImmutableSortedMultiset;
46import com.google.common.collect.ImmutableSortedSet;
47import com.google.common.collect.ImmutableTable;
48import com.google.common.collect.Iterables;
49import com.google.common.collect.LinkedHashMultimap;
50import com.google.common.collect.LinkedHashMultiset;
51import com.google.common.collect.ListMultimap;
52import com.google.common.collect.Lists;
53import com.google.common.collect.Maps;
54import com.google.common.collect.Multimap;
55import com.google.common.collect.Multiset;
56import com.google.common.collect.Ordering;
57import com.google.common.collect.Range;
58import com.google.common.collect.RowSortedTable;
59import com.google.common.collect.SetMultimap;
60import com.google.common.collect.Sets;
61import com.google.common.collect.SortedMultiset;
62import com.google.common.collect.Table;
63import com.google.common.collect.TreeBasedTable;
64import com.google.common.collect.TreeMultiset;
65import com.google.common.primitives.Primitives;
66import com.google.common.primitives.UnsignedInteger;
67import com.google.common.primitives.UnsignedLong;
68import com.google.common.reflect.AbstractInvocationHandler;
69import com.google.common.reflect.Invokable;
70import com.google.common.reflect.Parameter;
71import com.google.common.reflect.Reflection;
72import com.google.common.reflect.TypeToken;
73
74import java.io.ByteArrayInputStream;
75import java.io.File;
76import java.io.InputStream;
77import java.io.Reader;
78import java.io.StringReader;
79import java.lang.annotation.ElementType;
80import java.lang.annotation.Retention;
81import java.lang.annotation.RetentionPolicy;
82import java.lang.annotation.Target;
83import java.lang.reflect.Array;
84import java.lang.reflect.InvocationTargetException;
85import java.lang.reflect.Method;
86import java.lang.reflect.Type;
87import java.lang.reflect.TypeVariable;
88import java.math.BigDecimal;
89import java.math.BigInteger;
90import java.nio.Buffer;
91import java.nio.ByteBuffer;
92import java.nio.CharBuffer;
93import java.nio.DoubleBuffer;
94import java.nio.FloatBuffer;
95import java.nio.IntBuffer;
96import java.nio.LongBuffer;
97import java.nio.ShortBuffer;
98import java.nio.charset.Charset;
99import java.util.ArrayList;
100import java.util.Arrays;
101import java.util.Collection;
102import java.util.Comparator;
103import java.util.Currency;
104import java.util.HashMap;
105import java.util.HashSet;
106import java.util.LinkedHashMap;
107import java.util.LinkedHashSet;
108import java.util.LinkedList;
109import java.util.List;
110import java.util.Locale;
111import java.util.Map;
112import java.util.Set;
113import java.util.SortedMap;
114import java.util.SortedSet;
115import java.util.TreeMap;
116import java.util.TreeSet;
117import java.util.concurrent.ConcurrentMap;
118import java.util.concurrent.atomic.AtomicInteger;
119import java.util.regex.Pattern;
120
121import javax.annotation.Nullable;
122
123/**
124 * Generates fresh instances of types that are different from each other (if possible).
125 *
126 * @author Ben Yu
127 */
128class FreshValueGenerator {
129
130  private static final ImmutableMap<Class<?>, Method> GENERATORS;
131  static {
132    ImmutableMap.Builder<Class<?>, Method> builder =
133        ImmutableMap.builder();
134    for (Method method : FreshValueGenerator.class.getDeclaredMethods()) {
135      if (method.isAnnotationPresent(Generates.class)) {
136        builder.put(method.getReturnType(), method);
137      }
138    }
139    GENERATORS = builder.build();
140  }
141
142  private final AtomicInteger differentiator = new AtomicInteger(1);
143  private final ListMultimap<Class<?>, Object> sampleInstances = ArrayListMultimap.create();
144  private final Set<Type> generatedOptionalTypes = Sets.newHashSet();
145
146  <T> void addSampleInstances(Class<T> type, Iterable<? extends T> instances) {
147    sampleInstances.putAll(checkNotNull(type), checkNotNull(instances));
148  }
149
150  /**
151   * Returns a fresh instance for {@code type} if possible. The returned instance could be:
152   * <ul>
153   * <li>exactly of the given type, including generic type parameters, such as
154   *     {@code ImmutableList<String>};
155   * <li>of the raw type;
156   * <li>null if no fresh value can be generated.
157   * </ul>
158   */
159  @Nullable Object generate(TypeToken<?> type) {
160    Class<?> rawType = type.getRawType();
161    List<Object> samples = sampleInstances.get(rawType);
162    Object sample = nextInstance(samples, null);
163    if (sample != null) {
164      return sample;
165    }
166    if (rawType.isEnum()) {
167      return nextInstance(rawType.getEnumConstants(), null);
168    }
169    if (type.isArray()) {
170      TypeToken<?> componentType = type.getComponentType();
171      Object array = Array.newInstance(componentType.getRawType(), 1);
172      Array.set(array, 0, generate(componentType));
173      return array;
174    }
175    if (rawType == Optional.class && generatedOptionalTypes.add(type.getType())) {
176      // For any Optional<T>, we'll first generate absent(). The next call generates a distinct
177      // value of T to be wrapped in Optional.of().
178      return Optional.absent();
179    }
180    Method generator = GENERATORS.get(rawType);
181    if (generator != null) {
182      ImmutableList<Parameter> params = Invokable.from(generator).getParameters();
183      List<Object> args = Lists.newArrayListWithCapacity(params.size());
184      TypeVariable<?>[] typeVars = rawType.getTypeParameters();
185      for (int i = 0; i < params.size(); i++) {
186        TypeToken<?> paramType = type.resolveType(typeVars[i]);
187        // We require all @Generates methods to either be parameter-less or accept non-null
188        // fresh values for their generic parameter types.
189        Object argValue = generate(paramType);
190        if (argValue == null) {
191          // When a parameter of a @Generates method cannot be created,
192          // The type most likely is a collection.
193          // Our distinct proxy doesn't work for collections.
194          // So just refuse to generate.
195          return null;
196        }
197        args.add(argValue);
198      }
199      try {
200        return generator.invoke(this, args.toArray());
201      } catch (InvocationTargetException e) {
202        Throwables.propagate(e.getCause());
203      } catch (Exception e) {
204        throw Throwables.propagate(e);
205      }
206    }
207    return defaultGenerate(rawType);
208  }
209
210  @Nullable final <T> T generate(Class<T> type) {
211    return Primitives.wrap(type).cast(generate(TypeToken.of(type)));
212  }
213
214  private <T> T defaultGenerate(Class<T> rawType) {
215    if (rawType.isInterface()) {
216      // always create a new proxy
217      return newProxy(rawType);
218    }
219    return ArbitraryInstances.get(rawType);
220  }
221
222  final <T> T newProxy(final Class<T> interfaceType) {
223    return Reflection.newProxy(interfaceType, new FreshInvocationHandler(interfaceType));
224  }
225
226  private final class FreshInvocationHandler extends AbstractInvocationHandler {
227    private final int identity = freshInt();
228    private final Class<?> interfaceType;
229
230    FreshInvocationHandler(Class<?> interfaceType) {
231      this.interfaceType = interfaceType;
232    }
233
234    @Override protected Object handleInvocation(Object proxy, Method method, Object[] args) {
235      return interfaceMethodCalled(interfaceType, method);
236    }
237
238    @Override public int hashCode() {
239      return identity;
240    }
241
242    @Override public boolean equals(@Nullable Object obj) {
243      if (obj instanceof FreshInvocationHandler) {
244        FreshInvocationHandler that = (FreshInvocationHandler) obj;
245        return identity == that.identity;
246      }
247      return false;
248    }
249
250    @Override public String toString() {
251      return paramString(interfaceType, identity);
252    }
253  }
254
255  /** Subclasses can override to provide different return value for proxied interface methods. */
256  Object interfaceMethodCalled(
257      @SuppressWarnings("unused") Class<?> interfaceType,
258      @SuppressWarnings("unused") Method method) {
259    throw new UnsupportedOperationException();
260  }
261
262  private <T> T nextInstance(T[] instances, T defaultValue) {
263    return nextInstance(Arrays.asList(instances), defaultValue);
264  }
265
266  private <T> T nextInstance(Collection<T> instances, T defaultValue) {
267    if (instances.isEmpty()) {
268      return defaultValue;
269    }
270    // freshInt() is 1-based.
271    return Iterables.get(instances, (freshInt() - 1) % instances.size());
272  }
273
274  private static String paramString(Class<?> type, int i) {
275    return type.getSimpleName() + '@' + i;
276  }
277
278  /**
279   * Annotates a method to be the instance generator of a certain type. The return type is the
280   * generated type. The method parameters are non-null fresh values for each method type variable
281   * in the same type variable declaration order of the return type.
282   */
283  @Target(ElementType.METHOD)
284  @Retention(RetentionPolicy.RUNTIME)
285  private @interface Generates {}
286
287  @Generates private Class<?> freshClass() {
288    return nextInstance(
289        ImmutableList.of(
290            int.class, long.class, void.class,
291            Object.class, Object[].class, Iterable.class),
292        Object.class);
293  }
294
295  @Generates private Object freshObject() {
296    return freshString();
297  }
298
299  @Generates private Number freshNumber() {
300    return freshInt();
301  }
302
303  @Generates private int freshInt() {
304    return differentiator.getAndIncrement();
305  }
306
307  @Generates private Integer freshInteger() {
308    return new Integer(freshInt());
309  }
310
311  @Generates private long freshLong() {
312    return freshInt();
313  }
314
315  @Generates private Long freshLongObject() {
316    return new Long(freshLong());
317  }
318
319  @Generates private float freshFloat() {
320    return freshInt();
321  }
322
323  @Generates private Float freshFloatObject() {
324    return new Float(freshFloat());
325  }
326
327  @Generates private double freshDouble() {
328    return freshInt();
329  }
330
331  @Generates private Double freshDoubleObject() {
332    return new Double(freshDouble());
333  }
334
335  @Generates private short freshShort() {
336    return (short) freshInt();
337  }
338
339  @Generates private Short freshShortObject() {
340    return new Short(freshShort());
341  }
342
343  @Generates private byte freshByte() {
344    return (byte) freshInt();
345  }
346
347  @Generates private Byte freshByteObject() {
348    return new Byte(freshByte());
349  }
350
351  @Generates private char freshChar() {
352    return freshString().charAt(0);
353  }
354
355  @Generates private Character freshCharacter() {
356    return new Character(freshChar());
357  }
358
359  @Generates private boolean freshBoolean() {
360    return freshInt() % 2 == 0;
361  }
362
363  @Generates private Boolean freshBooleanObject() {
364    return new Boolean(freshBoolean());
365  }
366
367  @Generates private UnsignedInteger freshUnsignedInteger() {
368    return UnsignedInteger.fromIntBits(freshInt());
369  }
370
371  @Generates private UnsignedLong freshUnsignedLong() {
372    return UnsignedLong.fromLongBits(freshLong());
373  }
374
375  @Generates private BigInteger freshBigInteger() {
376    return BigInteger.valueOf(freshInt());
377  }
378
379  @Generates private BigDecimal freshBigDecimal() {
380    return BigDecimal.valueOf(freshInt());
381  }
382
383  @Generates private CharSequence freshCharSequence() {
384    return freshString();
385  }
386
387  @Generates private String freshString() {
388    return Integer.toString(freshInt());
389  }
390
391  @Generates private Comparable<?> freshComparable() {
392    return freshString();
393  }
394
395  @Generates private Pattern freshPattern() {
396    return Pattern.compile(freshString());
397  }
398
399  @Generates private Charset freshCharset() {
400    return nextInstance(Charset.availableCharsets().values(), Charsets.UTF_8);
401  }
402
403  @Generates private Locale freshLocale() {
404    return nextInstance(Locale.getAvailableLocales(), Locale.US);
405  }
406
407  @Generates private Currency freshCurrency() {
408    for (Set<Locale> uselessLocales = Sets.newHashSet(); ; ) {
409      Locale locale = freshLocale();
410      if (uselessLocales.contains(locale)) { // exhausted all locales
411        return Currency.getInstance(Locale.US);
412      }
413      try {
414        return Currency.getInstance(locale);
415      } catch (IllegalArgumentException e) {
416        uselessLocales.add(locale);
417      }
418    }
419  }
420
421  // common.base
422  @Generates private <T> Optional<T> freshOptional(T value) {
423    return Optional.of(value);
424  }
425
426  @Generates private Joiner freshJoiner() {
427    return Joiner.on(freshString());
428  }
429
430  @Generates private Splitter freshSplitter() {
431    return Splitter.on(freshString());
432  }
433
434  @Generates private <T> Equivalence<T> freshEquivalence() {
435    return new Equivalence<T>() {
436      @Override protected boolean doEquivalent(T a, T b) {
437        return false;
438      }
439      @Override protected int doHash(T t) {
440        return 0;
441      }
442      final String string = paramString(Equivalence.class, freshInt());
443      @Override public String toString() {
444        return string;
445      }
446    };
447  }
448
449  @Generates private CharMatcher freshCharMatcher() {
450    return new CharMatcher() {
451      @Override public boolean matches(char c) {
452        return false;
453      }
454      final String string = paramString(CharMatcher.class, freshInt());
455      @Override public String toString() {
456        return string;
457      }
458    };
459  }
460
461  @Generates private Ticker freshTicker() {
462    return new Ticker() {
463      @Override public long read() {
464        return 0;
465      }
466      final String string = paramString(Ticker.class, freshInt());
467      @Override public String toString() {
468        return string;
469      }
470    };
471  }
472
473  // collect
474  @Generates private <T> Comparator<T> freshComparator() {
475    return freshOrdering();
476  }
477
478  @Generates private <T> Ordering<T> freshOrdering() {
479    return new Ordering<T>() {
480      @Override public int compare(T left, T right) {
481        return 0;
482      }
483      final String string = paramString(Ordering.class, freshInt());
484      @Override public String toString() {
485        return string;
486      }
487    };
488  }
489
490  @Generates private static <C extends Comparable> Range<C> freshRange(C freshElement) {
491    return Range.singleton(freshElement);
492  }
493
494  @Generates private static <E> Iterable<E> freshIterable(E freshElement) {
495    return freshList(freshElement);
496  }
497
498  @Generates private static <E> Collection<E> freshCollection(E freshElement) {
499    return freshList(freshElement);
500  }
501
502  @Generates private static <E> List<E> freshList(E freshElement) {
503    return freshArrayList(freshElement);
504  }
505
506  @Generates private static <E> ArrayList<E> freshArrayList(E freshElement) {
507    ArrayList<E> list = Lists.newArrayList();
508    list.add(freshElement);
509    return list;
510  }
511
512  @Generates private static <E> LinkedList<E> freshLinkedList(E freshElement) {
513    LinkedList<E> list = Lists.newLinkedList();
514    list.add(freshElement);
515    return list;
516  }
517
518  @Generates private static <E> ImmutableList<E> freshImmutableList(E freshElement) {
519    return ImmutableList.of(freshElement);
520  }
521
522  @Generates private static <E> ImmutableCollection<E> freshImmutableCollection(E freshElement) {
523    return freshImmutableList(freshElement);
524  }
525
526  @Generates private static <E> Set<E> freshSet(E freshElement) {
527    return freshHashSet(freshElement);
528  }
529
530  @Generates private static <E> HashSet<E> freshHashSet(E freshElement) {
531    return freshLinkedHashSet(freshElement);
532  }
533
534  @Generates private static <E> LinkedHashSet<E> freshLinkedHashSet(E freshElement) {
535    LinkedHashSet<E> set = Sets.newLinkedHashSet();
536    set.add(freshElement);
537    return set;
538  }
539
540  @Generates private static <E> ImmutableSet<E> freshImmutableSet(E freshElement) {
541    return ImmutableSet.of(freshElement);
542  }
543
544  @Generates private static <E extends Comparable<? super E>> SortedSet<E>
545      freshSortedSet(E freshElement) {
546    return freshTreeSet(freshElement);
547  }
548
549  @Generates private static <E extends Comparable<? super E>> TreeSet<E> freshTreeSet(
550      E freshElement) {
551    TreeSet<E> set = Sets.newTreeSet();
552    set.add(freshElement);
553    return set;
554  }
555
556  @Generates private static <E extends Comparable<? super E>> ImmutableSortedSet<E>
557      freshImmutableSortedSet(E freshElement) {
558    return ImmutableSortedSet.of(freshElement);
559  }
560
561  @Generates private static <E> Multiset<E> freshMultiset(E freshElement) {
562    return freshHashMultiset(freshElement);
563  }
564
565  @Generates private static <E> HashMultiset<E> freshHashMultiset(E freshElement) {
566    HashMultiset<E> multiset = HashMultiset.create();
567    multiset.add(freshElement);
568    return multiset;
569  }
570
571  @Generates private static <E> LinkedHashMultiset<E> freshLinkedHashMultiset(E freshElement) {
572    LinkedHashMultiset<E> multiset = LinkedHashMultiset.create();
573    multiset.add(freshElement);
574    return multiset;
575  }
576
577  @Generates private static <E> ImmutableMultiset<E> freshImmutableMultiset(E freshElement) {
578    return ImmutableMultiset.of(freshElement);
579  }
580
581  @Generates private static <E extends Comparable<E>> SortedMultiset<E> freshSortedMultiset(
582      E freshElement) {
583    return freshTreeMultiset(freshElement);
584  }
585
586  @Generates private static <E extends Comparable<E>> TreeMultiset<E> freshTreeMultiset(
587      E freshElement) {
588    TreeMultiset<E> multiset = TreeMultiset.create();
589    multiset.add(freshElement);
590    return multiset;
591  }
592
593  @Generates private static <E extends Comparable<E>> ImmutableSortedMultiset<E>
594      freshImmutableSortedMultiset(E freshElement) {
595    return ImmutableSortedMultiset.of(freshElement);
596  }
597
598  @Generates private static <K, V> Map<K, V> freshMap(K key, V value) {
599    return freshHashdMap(key, value);
600  }
601
602  @Generates private static <K, V> HashMap<K, V> freshHashdMap(K key, V value) {
603    return freshLinkedHashMap(key, value);
604  }
605
606  @Generates private static <K, V> LinkedHashMap<K, V> freshLinkedHashMap(K key, V value) {
607    LinkedHashMap<K, V> map = Maps.newLinkedHashMap();
608    map.put(key, value);
609    return map;
610  }
611
612  @Generates private static <K, V> ImmutableMap<K, V> freshImmutableMap(K key, V value) {
613    return ImmutableMap.of(key, value);
614  }
615
616  @Generates private static <K, V> ConcurrentMap<K, V> freshConcurrentMap(K key, V value) {
617    ConcurrentMap<K, V> map = Maps.newConcurrentMap();
618    map.put(key, value);
619    return map;
620  }
621
622  @Generates private static <K extends Comparable<? super K>, V> SortedMap<K, V>
623      freshSortedMap(K key, V value) {
624    return freshTreeMap(key, value);
625  }
626
627  @Generates private static <K extends Comparable<? super K>, V> TreeMap<K, V> freshTreeMap(
628      K key, V value) {
629    TreeMap<K, V> map = Maps.newTreeMap();
630    map.put(key, value);
631    return map;
632  }
633
634  @Generates private static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
635      freshImmutableSortedMap(K key, V value) {
636    return ImmutableSortedMap.of(key, value);
637  }
638
639  @Generates private static <K, V> Multimap<K, V> freshMultimap(K key, V value) {
640    return freshListMultimap(key, value);
641  }
642
643  @Generates private static <K, V> ImmutableMultimap<K, V> freshImmutableMultimap(K key, V value) {
644    return ImmutableMultimap.of(key, value);
645  }
646
647  @Generates private static <K, V> ListMultimap<K, V> freshListMultimap(K key, V value) {
648    return freshArrayListMultimap(key, value);
649  }
650
651  @Generates private static <K, V> ArrayListMultimap<K, V> freshArrayListMultimap(K key, V value) {
652    ArrayListMultimap<K, V> multimap = ArrayListMultimap.create();
653    multimap.put(key, value);
654    return multimap;
655  }
656
657  @Generates private static <K, V> ImmutableListMultimap<K, V> freshImmutableListMultimap(
658      K key, V value) {
659    return ImmutableListMultimap.of(key, value);
660  }
661
662  @Generates private static <K, V> SetMultimap<K, V> freshSetMultimap(K key, V value) {
663    return freshLinkedHashMultimap(key, value);
664  }
665
666  @Generates private static <K, V> HashMultimap<K, V> freshHashMultimap(K key, V value) {
667    HashMultimap<K, V> multimap = HashMultimap.create();
668    multimap.put(key, value);
669    return multimap;
670  }
671
672  @Generates private static <K, V> LinkedHashMultimap<K, V> freshLinkedHashMultimap(
673      K key, V value) {
674    LinkedHashMultimap<K, V> multimap = LinkedHashMultimap.create();
675    multimap.put(key, value);
676    return multimap;
677  }
678
679  @Generates private static <K, V> ImmutableSetMultimap<K, V> freshImmutableSetMultimap(
680      K key, V value) {
681    return ImmutableSetMultimap.of(key, value);
682  }
683
684  @Generates private static <K, V> BiMap<K, V> freshBimap(K key, V value) {
685    return freshHashBiMap(key, value);
686  }
687
688  @Generates private static <K, V> HashBiMap<K, V> freshHashBiMap(K key, V value) {
689    HashBiMap<K, V> bimap = HashBiMap.create();
690    bimap.put(key, value);
691    return bimap;
692  }
693
694  @Generates private static <K, V> ImmutableBiMap<K, V> freshImmutableBimap(
695      K key, V value) {
696    return ImmutableBiMap.of(key, value);
697  }
698
699  @Generates private static <R, C, V> Table<R, C, V> freshTable(R row, C column, V value) {
700    return freshHashBasedTable(row, column, value);
701  }
702
703  @Generates private static <R, C, V> HashBasedTable<R, C, V> freshHashBasedTable(
704      R row, C column, V value) {
705    HashBasedTable<R, C, V> table = HashBasedTable.create();
706    table.put(row, column, value);
707    return table;
708  }
709
710  @SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such
711  @Generates private static <R extends Comparable, C extends Comparable, V> RowSortedTable<R, C, V>
712      freshRowSortedTable(R row, C column, V value) {
713    return freshTreeBasedTable(row, column, value);
714  }
715
716  @SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such
717  @Generates private static <R extends Comparable, C extends Comparable, V> TreeBasedTable<R, C, V>
718      freshTreeBasedTable(R row, C column, V value) {
719    TreeBasedTable<R, C, V> table = TreeBasedTable.create();
720    table.put(row, column, value);
721    return table;
722  }
723
724  @Generates private static <R, C, V> ImmutableTable<R, C, V> freshImmutableTable(
725      R row, C column, V value) {
726    return ImmutableTable.of(row, column, value);
727  }
728
729  // common.reflect
730  @Generates private TypeToken<?> freshTypeToken() {
731    return TypeToken.of(freshClass());
732  }
733
734  // io types
735  @Generates private File freshFile() {
736    return new File(freshString());
737  }
738
739  @Generates private static ByteArrayInputStream freshByteArrayInputStream() {
740    return new ByteArrayInputStream(new byte[0]);
741  }
742
743  @Generates private static InputStream freshInputStream() {
744    return freshByteArrayInputStream();
745  }
746
747  @Generates private StringReader freshStringReader() {
748    return new StringReader(freshString());
749  }
750
751  @Generates private Reader freshReader() {
752    return freshStringReader();
753  }
754
755  @Generates private Readable freshReadable() {
756    return freshReader();
757  }
758
759  @Generates private Buffer freshBuffer() {
760    return freshCharBuffer();
761  }
762
763  @Generates private CharBuffer freshCharBuffer() {
764    return CharBuffer.allocate(freshInt());
765  }
766
767  @Generates private ByteBuffer freshByteBuffer() {
768    return ByteBuffer.allocate(freshInt());
769  }
770
771  @Generates private ShortBuffer freshShortBuffer() {
772    return ShortBuffer.allocate(freshInt());
773  }
774
775  @Generates private IntBuffer freshIntBuffer() {
776    return IntBuffer.allocate(freshInt());
777  }
778
779  @Generates private LongBuffer freshLongBuffer() {
780    return LongBuffer.allocate(freshInt());
781  }
782
783  @Generates private FloatBuffer freshFloatBuffer() {
784    return FloatBuffer.allocate(freshInt());
785  }
786
787  @Generates private DoubleBuffer freshDoubleBuffer() {
788    return DoubleBuffer.allocate(freshInt());
789  }
790}
791