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