From b0fb449b2268bc1e57fd99e00f3049175abd2126 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Wed, 20 Oct 2021 09:11:26 -0700 Subject: [PATCH 01/21] Improve JDK compatibility --- README-typetools.md | 3 +++ guava/cfMavenCentral.xml | 8 -------- guava/pom.xml | 6 +++--- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/README-typetools.md b/README-typetools.md index 5c191148d14c..d0e748e7ea9e 100644 --- a/README-typetools.md +++ b/README-typetools.md @@ -68,6 +68,9 @@ Whenever a Checker Framework release is made: To update to a newer version of the upstream library ---------------------------------------------------- +First, update to use the latest Checker Framework by editing file +`guava/pom.xml`. Ensure that type-checking succeeds. + Check for a release at https://github.com/google/guava/releases . If there has been one since the last time this repository was pulled, diff --git a/guava/cfMavenCentral.xml b/guava/cfMavenCentral.xml index 117e82d48d2f..07bf025a9ca0 100644 --- a/guava/cfMavenCentral.xml +++ b/guava/cfMavenCentral.xml @@ -37,14 +37,6 @@ https://www.cs.washington.edu/ - - wmdietl - Werner M. Dietl - wdietl@uwaterloo.ca - University of Waterloo - http://uwaterloo.ca/ - - Suzanne Millstein Suzanne Millstein diff --git a/guava/pom.xml b/guava/pom.xml index f024d9ff58bd..0ab7ddb4c63d 100644 --- a/guava/pom.xml +++ b/guava/pom.xml @@ -74,7 +74,7 @@ org.checkerframework checker - 3.12.0 + 3.13.0 @@ -376,9 +376,9 @@ - jdk16 + jdk17 - 16 + [16,) From 615207f31f833c284880be0a7ee363da9aaba311 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Thu, 2 Dec 2021 16:36:56 -0800 Subject: [PATCH 02/21] Use Checker Framework version 3.19.0 --- README-typetools.md | 3 ++- guava/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README-typetools.md b/README-typetools.md index d0e748e7ea9e..4a2e614e9114 100644 --- a/README-typetools.md +++ b/README-typetools.md @@ -69,7 +69,8 @@ To update to a newer version of the upstream library ---------------------------------------------------- First, update to use the latest Checker Framework by editing file -`guava/pom.xml`. Ensure that type-checking succeeds. +`pom.xml` (for `checker-qual`) and `guava/pom.xml` (for `checker`). +Make a pull request to ensure that type-checking succeeds. Check for a release at https://github.com/google/guava/releases diff --git a/guava/pom.xml b/guava/pom.xml index 0ab7ddb4c63d..ab65fb2e9a79 100644 --- a/guava/pom.xml +++ b/guava/pom.xml @@ -74,7 +74,7 @@ org.checkerframework checker - 3.13.0 + 3.19.0 diff --git a/pom.xml b/pom.xml index 74ebce71142b..eb05a1aa331f 100644 --- a/pom.xml +++ b/pom.xml @@ -274,7 +274,7 @@ org.checkerframework checker-qual - 3.12.0 + 3.19.0 com.google.errorprone From b419ba82f9ad69a431723c73bb5912236767e494 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 31 Jan 2023 11:17:47 -0800 Subject: [PATCH 03/21] Expand note --- README-typetools.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README-typetools.md b/README-typetools.md index 4a2e614e9114..f552fdfd2b47 100644 --- a/README-typetools.md +++ b/README-typetools.md @@ -84,8 +84,9 @@ git pull https://github.com/google/guava ``` and then re-build to ensure that typechecking still works. -Doing this `git pull` permits incremental resolution of merge conflicts, -but makes it difficult to re-release a given version of Guava. +Note: Doing this `git pull` command +makes it difficult to re-release a given version of Guava, +compared to pulling in the tag corresponding to a release. If you wish to see a simplified diff between this fork of Guava and upstream (to make sure that you did not make any mistakes when resolving merge conflicts): From 407e13feb22148907bbf1cc252a295578767ec75 Mon Sep 17 00:00:00 2001 From: Mark Roberts Date: Tue, 14 Feb 2023 10:53:17 -0800 Subject: [PATCH 04/21] update checker framework; clean up some suppressions --- guava/pom.xml | 28 +++++++-- .../com/google/common/base/CharMatcher.java | 43 +------------ .../google/common/base/SmallCharMatcher.java | 2 +- guava/src/com/google/common/base/Strings.java | 15 ----- .../com/google/common/cache/LongAdder.java | 22 ++++--- .../common/collect/CollectSpliterators.java | 2 +- .../google/common/collect/CompactHashMap.java | 16 ++--- .../google/common/collect/CompactHashSet.java | 14 +++-- .../google/common/collect/ImmutableSet.java | 1 + .../com/google/common/collect/Multiset.java | 11 ++-- .../src/com/google/common/collect/Table.java | 18 +++--- .../escape/ArrayBasedUnicodeEscaper.java | 3 - .../google/common/escape/UnicodeEscaper.java | 19 ------ .../graph/DirectedGraphConnections.java | 2 +- .../com/google/common/graph/Traverser.java | 3 +- .../google/common/hash/AbstractHasher.java | 9 +-- .../AbstractNonStreamingHashFunction.java | 10 +-- .../common/hash/FarmHashFingerprint64.java | 18 +----- guava/src/com/google/common/hash/Funnels.java | 13 ++-- .../src/com/google/common/hash/HashCode.java | 8 +-- guava/src/com/google/common/hash/Hashing.java | 7 ++- .../src/com/google/common/hash/LongAdder.java | 23 ++++--- .../hash/MessageDigestHashFunction.java | 2 +- .../com/google/common/hash/PrimitiveSink.java | 2 +- .../com/google/common/io/BaseEncoding.java | 29 +-------- .../src/com/google/common/io/ByteSource.java | 8 +-- .../src/com/google/common/io/ByteStreams.java | 18 ++---- .../common/io/FileBackedOutputStream.java | 3 +- .../src/com/google/common/math/LongMath.java | 62 +++++++------------ .../src/com/google/common/math/Quantiles.java | 41 ++---------- .../com/google/common/primitives/Ints.java | 13 +--- .../com/google/common/primitives/Longs.java | 29 +++------ .../common/primitives/UnsignedInteger.java | 7 ++- .../common/primitives/UnsignedLong.java | 34 +++++++--- .../common/primitives/UnsignedLongs.java | 16 ++++- .../common/util/concurrent/AtomicDouble.java | 22 ++++--- .../common/util/concurrent/ClosingFuture.java | 3 +- pom.xml | 2 +- 38 files changed, 224 insertions(+), 354 deletions(-) diff --git a/guava/pom.xml b/guava/pom.xml index ab65fb2e9a79..d0643e25e487 100644 --- a/guava/pom.xml +++ b/guava/pom.xml @@ -19,18 +19,33 @@ org.checkerframework.checker.index.IndexChecker,org.checkerframework.checker.nullness.NullnessChecker,org.checkerframework.checker.signedness.SignednessChecker + index + base|primitives|escape|math|io|hash - + + - + + + process-sources + + + + false + + + false @@ -74,7 +89,7 @@ org.checkerframework checker - 3.19.0 + 3.30.0 @@ -131,7 +146,8 @@ 10000 true - trued + + ${javac.verbose} ${checkerframework.checkers} @@ -139,9 +155,12 @@ ${additionalargs} ${checkerframework.extraargs} ${checkerframework.extraargs2} + -AsuppressWarnings=${checkerframework.suppress} -AuseDefaultsForUncheckedCode=source,bytecode -Awarns + -AshowSuppressWarningsStrings + -AwarnUnneededSuppressions @@ -194,6 +213,7 @@ compile + ${main-compile.skip} **/Java8Usage.java diff --git a/guava/src/com/google/common/base/CharMatcher.java b/guava/src/com/google/common/base/CharMatcher.java index 842a642e0fd4..f1d509c29262 100644 --- a/guava/src/com/google/common/base/CharMatcher.java +++ b/guava/src/com/google/common/base/CharMatcher.java @@ -319,7 +319,6 @@ public static CharMatcher isNot(final char match) { * The CharSequence is not mutated, therefore after checking its length, * accesses to lower indices are safe. */ - @SuppressWarnings("upperbound:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/188 public static CharMatcher anyOf(final CharSequence sequence) { switch (sequence.length()) { case 0: @@ -453,7 +452,7 @@ public String toString() { /** * Helper method for {@link #precomputedInternal} that doesn't test if the negation is cheaper. */ - @SuppressWarnings("index") // table has bits if totalCharacters is sufficiently large + @SuppressWarnings("signedness:cast.unsafe") // distance between true bits will fit in char @GwtIncompatible // SmallCharMatcher private static CharMatcher precomputedPositive( int totalCharacters, BitSet table, String description) { @@ -608,7 +607,6 @@ public boolean matchesNoneOf(CharSequence sequence) { /* * count is incremented at most sequence.length() times */ - @SuppressWarnings("unary.increment.type.incompatible") // variable incremented at most IndexOrHigh times public @IndexOrHigh("#1") int countIn(CharSequence sequence) { @IndexOrHigh("#1") int count = 0; for (int i = 0; i < sequence.length(); i++) { @@ -629,20 +627,6 @@ public boolean matchesNoneOf(CharSequence sequence) { * * ... returns {@code "bzr"}. */ - @SuppressWarnings({ - /* - * at entry to OUT, pos is IndexFor("string"), - * and after each pos++, it is checked against chars.length - * if equal, pos is not incremented anymore - * therefore both pos++ are safe - */ - "upperbound:unary.increment.type.incompatible", // index incremented in nested loop with break - "upperbound:array.access.unsafe.high", "upperbound:argument.type.incompatible", // https://github.com/kelloggm/checker-framework/issues/204 - /* - * spread <= pos, therefore pos-spread >= 0 - */ - "lowerbound:array.access.unsafe.low", "lowerbound:argument.type.incompatible" // https://github.com/kelloggm/checker-framework/issues/158 - }) public String removeFrom(CharSequence sequence) { String string = sequence.toString(); @GTENegativeOne @LTEqLengthOf("string") int pos = indexIn(string); @@ -744,9 +728,6 @@ public String replaceFrom(CharSequence sequence, char replacement) { * replacementLen should be @IndexOrHigh("replacement") * indexIn should return @IndexOrLow("#1") */ - @SuppressWarnings({ - "upperbound:argument.type.incompatible", // https://github.com/kelloggm/checker-framework/issues/188 - }) public String replaceFrom(CharSequence sequence, CharSequence replacement) { int replacementLen = replacement.length(); if (replacementLen == 0) { @@ -879,7 +860,6 @@ public String trimTrailingFrom(CharSequence sequence) { * i should be @IndexOrHigh("sequence") * inside the loop, i is @IndexFor("sequence") */ - @SuppressWarnings("upperbound:argument.type.incompatible") // refinement by inequality with expression referring to length in a local variable public String collapseFrom(CharSequence sequence, char replacement) { // This implementation avoids unnecessary allocation. int len = sequence.length(); @@ -909,9 +889,6 @@ public String collapseFrom(CharSequence sequence, char replacement) { * last should be @IndexFor("sequence") * last >= first */ - @SuppressWarnings({ - "lowerbound:argument.type.incompatible", // https://github.com/kelloggm/checker-framework/issues/158 - }) public String trimAndCollapseFrom(CharSequence sequence, char replacement) { // This implementation avoids unnecessary allocation. int len = sequence.length(); @@ -977,7 +954,6 @@ public String toString() { * Returns the Java Unicode escape sequence for the given {@code char}, in the form "\u12AB" where * "12AB" is the four hexadecimal digits representing the 16-bit code unit. */ - @SuppressWarnings("index") // https://github.com/typetools/checker-framework/issues/2540 private static String showCharacter(char c) { String hex = "0123456789ABCDEF"; char[] tmp = {'\\', 'u', '\0', '\0', '\0', '\0'}; @@ -1048,7 +1024,6 @@ private BitSetMatcher(BitSet table, String description) { } @Override - @SuppressWarnings("lowerbound:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/192 char should be @NonNegative public boolean matches(char c) { return table.get(c); } @@ -1078,7 +1053,6 @@ public boolean matches(char c) { /* * If length() != 0, then sequence is MinLen(1), so 0 is LTLengthOf(sequence) */ - @SuppressWarnings("upperbound:return.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/188 @Override public @IndexOrLow("#1") int indexIn(CharSequence sequence) { return (sequence.length() == 0) ? -1 : 0; @@ -1087,7 +1061,6 @@ public boolean matches(char c) { /* * If start != length(), then start is LTLengthOf(sequence) */ - @SuppressWarnings("upperbound:return.type.incompatible") // Refine index by comparison to length method @Override public @IndexOrLow("#1") int indexIn(CharSequence sequence, @IndexOrHigh("#1") int start) { int length = sequence.length(); @@ -1292,14 +1265,12 @@ static final class Whitespace extends NamedFastMatcher { } @Override - @SuppressWarnings("index:argument.type.incompatible") // unsigned right shift on int public boolean matches(char c) { return TABLE.charAt((MULTIPLIER * c) >>> SHIFT) == c; } @GwtIncompatible // used only from other GwtIncompatible code @Override - @SuppressWarnings("lowerbound:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/192 char should be @NonNegative void setBits(BitSet table) { for (int i = 0; i < TABLE.length(); i++) { table.set(TABLE.charAt(i)); @@ -1410,7 +1381,6 @@ private static final class Digit extends RangesMatcher { return ZEROES.toCharArray(); } - @SuppressWarnings("index") // https://github.com/typetools/checker-framework/issues/2540 private static char @SameLen("ZEROES")[] nines() { char[] nines = new char[ZEROES.length()]; for (int i = 0; i < ZEROES.length(); i++) { @@ -1421,7 +1391,6 @@ private static final class Digit extends RangesMatcher { static final Digit INSTANCE = new Digit(); - @SuppressWarnings("samelen:argument.type.incompatible") // SameLen on method calls private Digit() { super("CharMatcher.digit()", zeroes(), nines()); } @@ -1537,7 +1506,6 @@ private static final class Invisible extends RangesMatcher { static final Invisible INSTANCE = new Invisible(); - @SuppressWarnings("samelen:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/179 private Invisible() { super("CharMatcher.invisible()", RANGE_STARTS.toCharArray(), RANGE_ENDS.toCharArray()); } @@ -1548,7 +1516,6 @@ private static final class SingleWidth extends RangesMatcher { static final SingleWidth INSTANCE = new SingleWidth(); - @SuppressWarnings("samelen:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/179 private SingleWidth() { super( "CharMatcher.singleWidth()", @@ -1584,7 +1551,6 @@ public boolean matchesNoneOf(CharSequence sequence) { } @Override - @SuppressWarnings("lowerbound:return.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/193 public @IndexOrHigh("#1") int countIn(CharSequence sequence) { return sequence.length() - original.countIn(sequence); } @@ -1709,7 +1675,6 @@ public CharMatcher negate() { @GwtIncompatible // used only from other GwtIncompatible code @Override - @SuppressWarnings("lowerbound:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/192 char should be @NonNegative void setBits(BitSet table) { table.set(match); } @@ -1746,7 +1711,6 @@ public CharMatcher or(CharMatcher other) { @GwtIncompatible // used only from other GwtIncompatible code @Override - @SuppressWarnings("lowerbound:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/192 char should be @NonNegative void setBits(BitSet table) { table.set(0, match); table.set(match + 1, Character.MAX_VALUE + 1); @@ -1785,7 +1749,6 @@ public boolean matches(char c) { @GwtIncompatible // used only from other GwtIncompatible code @Override - @SuppressWarnings("lowerbound:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/192 char should be @NonNegative void setBits(BitSet table) { table.set(match1); table.set(match2); @@ -1814,7 +1777,6 @@ public boolean matches(char c) { @Override @GwtIncompatible // used only from other GwtIncompatible code - @SuppressWarnings("lowerbound:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/192 char should be @NonNegative void setBits(BitSet table) { for (char c : chars) { table.set(c); @@ -1851,7 +1813,6 @@ public boolean matches(char c) { @GwtIncompatible // used only from other GwtIncompatible code @Override - @SuppressWarnings("lowerbound:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/192 char should be @NonNegative void setBits(BitSet table) { table.set(startInclusive, endInclusive + 1); } @@ -1880,8 +1841,8 @@ public boolean matches(char c) { return predicate.apply(c); } - @SuppressWarnings("deprecation") // intentional; deprecation is for callers primarily @Override + @SuppressWarnings("signedness:type.argument") public boolean apply(Character character) { return predicate.apply(checkNotNull(character)); } diff --git a/guava/src/com/google/common/base/SmallCharMatcher.java b/guava/src/com/google/common/base/SmallCharMatcher.java index b57eef48d016..c0842c911b9f 100644 --- a/guava/src/com/google/common/base/SmallCharMatcher.java +++ b/guava/src/com/google/common/base/SmallCharMatcher.java @@ -90,7 +90,7 @@ private boolean checkFilter(int c) { /* * chars should be at most 65536 bits and not all zeroes */ - @SuppressWarnings("value:argument.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/197 + @SuppressWarnings("value:argument") // size is in range as arg to chooseTableSize static CharMatcher from(BitSet chars, String description) { // Compute the filter. long filter = 0; diff --git a/guava/src/com/google/common/base/Strings.java b/guava/src/com/google/common/base/Strings.java index 67ef68200300..8d86b71cb1ef 100644 --- a/guava/src/com/google/common/base/Strings.java +++ b/guava/src/com/google/common/base/Strings.java @@ -145,16 +145,6 @@ public static String padEnd(String string, int minLength, char padChar) { * {@code count} is zero) * @throws IllegalArgumentException if {@code count} is negative */ - @SuppressWarnings({ - "upperbound:argument.type.incompatible", "upperbound:assignment.type.incompatible", // https://github.com/kelloggm/checker-framework/issues/158 - /* - * After checking that n < size - n, we know that 2*n < size, - * therefore n << 1 < size, - * therefore n <<= 1 does not break IndexOrHigh("array"). - */ - "upperbound:compound.assignment.type.incompatible", // multiply index by 2 using bit shift - "lowerbound:argument.type.incompatible", // https://github.com/kelloggm/checker-framework/issues/193 - }) public static String repeat(String string, @NonNegative int count) { checkNotNull(string); // eager for GWT. @@ -188,7 +178,6 @@ public static String repeat(String string, @NonNegative int count) { * * @since 11.0 */ - @SuppressWarnings("index:unary.decrement.type.incompatible") // i-1 is @NonNegative means i-- is @NonNegative public static String commonPrefix(CharSequence a, CharSequence b) { checkNotNull(a); checkNotNull(b); @@ -212,10 +201,6 @@ public static String commonPrefix(CharSequence a, CharSequence b) { * * @since 11.0 */ - @SuppressWarnings({ - "lowerbound:argument.type.incompatible", // https://github.com/kelloggm/checker-framework/issues/193 - "lowerbound:unary.decrement.type.incompatible" // i-1 is @NonNegative means i-- is @NonNegative - }) public static String commonSuffix(CharSequence a, CharSequence b) { checkNotNull(a); checkNotNull(b); diff --git a/guava/src/com/google/common/cache/LongAdder.java b/guava/src/com/google/common/cache/LongAdder.java index f0c44ffbc697..9b09b63749e8 100644 --- a/guava/src/com/google/common/cache/LongAdder.java +++ b/guava/src/com/google/common/cache/LongAdder.java @@ -18,6 +18,8 @@ import java.io.Serializable; import java.util.concurrent.atomic.AtomicLong; +import org.checkerframework.common.value.qual.PolyValue; + /** * One or more variables that together maintain an initially zero {@code long} sum. When updates * (method {@link #add}) are contended across threads, the set of variables may grow dynamically to @@ -157,26 +159,30 @@ public String toString() { * @return the sum */ @Override - public long longValue() { - return sum(); + @SuppressWarnings("cast.unsafe") + public @PolyValue long longValue(@PolyValue LongAdder this) { + return (@PolyValue long) sum(); } /** Returns the {@link #sum} as an {@code int} after a narrowing primitive conversion. */ @Override - public int intValue() { - return (int) sum(); + @SuppressWarnings("cast.unsafe") + public @PolyValue int intValue(@PolyValue LongAdder this) { + return (@PolyValue int) sum(); } /** Returns the {@link #sum} as a {@code float} after a widening primitive conversion. */ @Override - public float floatValue() { - return (float) sum(); + @SuppressWarnings("cast.unsafe") + public @PolyValue float floatValue(@PolyValue LongAdder this) { + return (@PolyValue float) sum(); } /** Returns the {@link #sum} as a {@code double} after a widening primitive conversion. */ @Override - public double doubleValue() { - return (double) sum(); + @SuppressWarnings("cast.unsafe") + public @PolyValue double doubleValue(@PolyValue LongAdder this) { + return (@PolyValue double) sum(); } private void writeObject(ObjectOutputStream s) throws IOException { diff --git a/guava/src/com/google/common/collect/CollectSpliterators.java b/guava/src/com/google/common/collect/CollectSpliterators.java index 974f77fdc0ec..6bced4aa8e6e 100644 --- a/guava/src/com/google/common/collect/CollectSpliterators.java +++ b/guava/src/com/google/common/collect/CollectSpliterators.java @@ -302,7 +302,7 @@ OutSpliteratorT newFlatMapSpliterator( long estSplitSize); } - @Nullable @Weak OutSpliteratorT prefix; + @Weak @Nullable OutSpliteratorT prefix; final Spliterator from; final Function function; final Factory factory; diff --git a/guava/src/com/google/common/collect/CompactHashMap.java b/guava/src/com/google/common/collect/CompactHashMap.java index a68890e82b03..e44153aabfec 100644 --- a/guava/src/com/google/common/collect/CompactHashMap.java +++ b/guava/src/com/google/common/collect/CompactHashMap.java @@ -48,6 +48,9 @@ import java.util.function.BiFunction; import java.util.function.Consumer; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.nullness.qual.PolyNull; +import org.checkerframework.checker.signedness.qual.PolySigned; +import org.checkerframework.checker.signedness.qual.UnknownSignedness; /** * CompactHashMap is an implementation of a Map. All optional operations (put and remove) are @@ -138,7 +141,7 @@ public static CompactHashMap createWithExpectedSize(int expectedSiz *
  • null, if no entries have yet been added to the map * */ - @Nullable private transient Object table; + private transient @Nullable Object table; /** * Contains the logical entries, in the range of [0, size()). The high bits of each int are the @@ -439,14 +442,14 @@ private int indexOf(@Nullable Object key) { } @Override - public boolean containsKey(@Nullable Object key) { + public boolean containsKey(@Nullable @UnknownSignedness Object key) { @Nullable Map delegate = delegateOrNull(); return (delegate != null) ? delegate.containsKey(key) : indexOf(key) != -1; } @SuppressWarnings("unchecked") // known to be a V @Override - public V get(@Nullable Object key) { + public V get(@Nullable @UnknownSignedness Object key) { @Nullable Map delegate = delegateOrNull(); if (delegate != null) { return delegate.get(key); @@ -462,7 +465,7 @@ public V get(@Nullable Object key) { @CanIgnoreReturnValue @SuppressWarnings("unchecked") // known to be a V @Override - public @Nullable V remove(@Nullable Object key) { + public @Nullable V remove(@Nullable @UnknownSignedness Object key) { @Nullable Map delegate = delegateOrNull(); if (delegate != null) { return delegate.remove(key); @@ -629,7 +632,7 @@ class KeySetView extends Maps.KeySet { } @Override - public Object[] toArray() { + public @PolySigned Object[] toArray(CompactHashMap<@PolySigned K, @PolySigned V>.KeySetView this) { if (needsAllocArrays()) { return new Object[0]; } @@ -817,9 +820,8 @@ final class MapEntry extends AbstractMapEntry { this.lastKnownIndex = index; } - @Nullable @Override - public K getKey() { + public @Nullable K getKey() { return key; } diff --git a/guava/src/com/google/common/collect/CompactHashSet.java b/guava/src/com/google/common/collect/CompactHashSet.java index d54e16648143..d344da6597c4 100644 --- a/guava/src/com/google/common/collect/CompactHashSet.java +++ b/guava/src/com/google/common/collect/CompactHashSet.java @@ -45,6 +45,8 @@ import java.util.Spliterators; import java.util.function.Consumer; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.signedness.qual.PolySigned; +import org.checkerframework.checker.signedness.qual.UnknownSignedness; /** * CompactHashSet is an implementation of a Set. All optional operations (adding and removing) are @@ -155,7 +157,7 @@ public static CompactHashSet createWithExpectedSize(int expectedSize) { *
  • null, if no entries have yet been added to the map * */ - @Nullable private transient Object table; + private transient @Nullable Object table; /** * Contains the logical entries, in the range of [0, size()). The high bits of each int are the @@ -300,6 +302,7 @@ public boolean add(@Nullable E object) { int newEntryIndex = this.size; // current size, and pointer to the entry to be appended int newSize = newEntryIndex + 1; + @SuppressWarnings("signedness:argument") int hash = smearedHash(object); int mask = hashTableMask(); int tableIndex = hash & mask; @@ -348,6 +351,7 @@ public boolean add(@Nullable E object) { /** * Creates a fresh entry with the specified object at the specified position in the entry arrays. */ + @SuppressWarnings("signedness:assignment") void insertEntry(int entryIndex, @Nullable E object, int hash, int mask) { this.entries[entryIndex] = CompactHashing.maskCombine(hash, UNSET, mask); this.elements[entryIndex] = object; @@ -413,7 +417,7 @@ private int resizeTable(int mask, int newCapacity, int targetHash, int targetEnt } @Override - public boolean contains(@Nullable Object object) { + public boolean contains(@Nullable @UnknownSignedness Object object) { if (needsAllocArrays()) { return false; } @@ -442,7 +446,7 @@ public boolean contains(@Nullable Object object) { @CanIgnoreReturnValue @Override - public boolean remove(@Nullable Object object) { + public boolean remove(@Nullable @UnknownSignedness Object object) { if (needsAllocArrays()) { return false; } @@ -610,7 +614,7 @@ public boolean isEmpty() { } @Override - public Object[] toArray() { + public @PolySigned Object[] toArray(CompactHashSet<@PolySigned E> this) { if (needsAllocArrays()) { return new Object[0]; } @@ -660,6 +664,7 @@ public void trimToSize() { } @Override + @SuppressWarnings("signedness:argument") public void clear() { if (needsAllocArrays()) { return; @@ -680,6 +685,7 @@ public void clear() { } } + @SuppressWarnings("signedness:argument") private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); stream.writeInt(size()); diff --git a/guava/src/com/google/common/collect/ImmutableSet.java b/guava/src/com/google/common/collect/ImmutableSet.java index f2a8724897bb..9ee2d958c184 100644 --- a/guava/src/com/google/common/collect/ImmutableSet.java +++ b/guava/src/com/google/common/collect/ImmutableSet.java @@ -639,6 +639,7 @@ SetBuilderImpl review() { private static final double DESIRED_LOAD_FACTOR = 0.7; // If the set has this many elements, it will "max out" the table size + @SuppressWarnings("cast.unsafe") // cast float to int private static final int CUTOFF = (int) (MAX_TABLE_SIZE * DESIRED_LOAD_FACTOR); /** diff --git a/guava/src/com/google/common/collect/Multiset.java b/guava/src/com/google/common/collect/Multiset.java index 24e7b19f21da..b7fa165778ba 100644 --- a/guava/src/com/google/common/collect/Multiset.java +++ b/guava/src/com/google/common/collect/Multiset.java @@ -31,6 +31,7 @@ import java.util.function.Consumer; import java.util.function.ObjIntConsumer; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; @@ -111,7 +112,7 @@ public interface Multiset extends Collection { * @return the number of occurrences of the element in this multiset; possibly zero but never * negative */ - int count(@Nullable @CompatibleWith("E") Object element); + int count(@CompatibleWith("E") @Nullable Object element); // Bulk Operations @@ -172,7 +173,7 @@ public interface Multiset extends Collection { * @throws IllegalArgumentException if {@code occurrences} is negative */ @CanIgnoreReturnValue - int remove(@Nullable @CompatibleWith("E") Object element, int occurrences); + int remove(@CompatibleWith("E") @Nullable Object element, int occurrences); /** * Removes a single occurrence of the specified element from this multiset, if present. @@ -188,7 +189,7 @@ public interface Multiset extends Collection { */ @CanIgnoreReturnValue @Override - boolean remove(@Nullable Object element); + boolean remove(@Nullable @UnknownSignedness Object element); /** * Adds or removes the necessary occurrences of an element such that the element attains the @@ -356,7 +357,7 @@ default void forEachEntry(ObjIntConsumer action) { @Pure @Override // TODO(kevinb): caveats about equivalence-relation? - boolean equals(@Nullable Object object); + boolean equals(@Nullable @UnknownSignedness Object object); /** * Returns the hash code for this multiset. This is defined as the sum of @@ -405,7 +406,7 @@ default void forEachEntry(ObjIntConsumer action) { */ @Pure @Override - boolean contains(@Nullable Object element); + boolean contains(@Nullable @UnknownSignedness Object element); /** * Returns {@code true} if this multiset contains at least one occurrence of each element in the diff --git a/guava/src/com/google/common/collect/Table.java b/guava/src/com/google/common/collect/Table.java index 136ec1742521..bb9448adc7ec 100644 --- a/guava/src/com/google/common/collect/Table.java +++ b/guava/src/com/google/common/collect/Table.java @@ -67,29 +67,29 @@ public interface Table { * @param columnKey key of column to search for */ boolean contains( - @Nullable @CompatibleWith("R") Object rowKey, - @Nullable @CompatibleWith("C") Object columnKey); + @CompatibleWith("R") @Nullable Object rowKey, + @CompatibleWith("C") @Nullable Object columnKey); /** * Returns {@code true} if the table contains a mapping with the specified row key. * * @param rowKey key of row to search for */ - boolean containsRow(@Nullable @CompatibleWith("R") Object rowKey); + boolean containsRow(@CompatibleWith("R") @Nullable Object rowKey); /** * Returns {@code true} if the table contains a mapping with the specified column. * * @param columnKey key of column to search for */ - boolean containsColumn(@Nullable @CompatibleWith("C") Object columnKey); + boolean containsColumn(@CompatibleWith("C") @Nullable Object columnKey); /** * Returns {@code true} if the table contains a mapping with the specified value. * * @param value value to search for */ - boolean containsValue(@Nullable @CompatibleWith("V") Object value); + boolean containsValue(@CompatibleWith("V") @Nullable Object value); /** * Returns the value corresponding to the given row and column keys, or {@code null} if no such @@ -100,8 +100,8 @@ boolean contains( */ @Nullable V get( - @Nullable @CompatibleWith("R") Object rowKey, - @Nullable @CompatibleWith("C") Object columnKey); + @CompatibleWith("R") @Nullable Object rowKey, + @CompatibleWith("C") @Nullable Object columnKey); /** Returns {@code true} if the table contains no mappings. */ boolean isEmpty(); @@ -160,8 +160,8 @@ V get( @CanIgnoreReturnValue @Nullable V remove( - @Nullable @CompatibleWith("R") Object rowKey, - @Nullable @CompatibleWith("C") Object columnKey); + @CompatibleWith("R") @Nullable Object rowKey, + @CompatibleWith("C") @Nullable Object columnKey); // Views diff --git a/guava/src/com/google/common/escape/ArrayBasedUnicodeEscaper.java b/guava/src/com/google/common/escape/ArrayBasedUnicodeEscaper.java index ce6a3ad27b56..d98ad0563ea7 100644 --- a/guava/src/com/google/common/escape/ArrayBasedUnicodeEscaper.java +++ b/guava/src/com/google/common/escape/ArrayBasedUnicodeEscaper.java @@ -96,7 +96,6 @@ protected ArrayBasedUnicodeEscaper( * @param unsafeReplacement the default replacement for unsafe characters or null if no default * replacement is required */ - @SuppressWarnings("index:assignment.type.incompatible") // implementation sets formal parameter protected ArrayBasedUnicodeEscaper( ArrayBasedEscaperMap escaperMap, @NonNegative int safeMin, @@ -144,7 +143,6 @@ protected ArrayBasedUnicodeEscaper( * This is overridden to improve performance. Rough benchmarking shows that this almost doubles * the speed when processing strings that do not require any escaping. */ - @SuppressWarnings("lowerbound:array.access.unsafe.low")//char types are non negative: https://github.com/kelloggm/checker-framework/issues/192 @Override public final String escape(String s) { checkNotNull(s); // GWT specific check (do not optimize) @@ -179,7 +177,6 @@ protected final char[] escape(@NonNegative int cp) { } /* Overridden for performance. */ - @SuppressWarnings("lowerbound:array.access.unsafe.low")//char types are non negative: https://github.com/kelloggm/checker-framework/issues/192 @Override protected final @IndexOrHigh("#1") int nextEscapeIndex(CharSequence csq, @IndexOrHigh("#1") int index, @IndexOrHigh("#1") int end) { while (index < end) { diff --git a/guava/src/com/google/common/escape/UnicodeEscaper.java b/guava/src/com/google/common/escape/UnicodeEscaper.java index 9cb8b7a2b0e8..ca956066627f 100644 --- a/guava/src/com/google/common/escape/UnicodeEscaper.java +++ b/guava/src/com/google/common/escape/UnicodeEscaper.java @@ -133,9 +133,6 @@ public String escape(String string) { * @throws IllegalArgumentException if the scanned sub-sequence of {@code csq} contains invalid * surrogate pairs */ - @SuppressWarnings("upperbound:compound.assignment.type.incompatible")/* (1) In char arrays and CharSequence and its subclasses, two chars are used to represent - unicode characters that are outside the range of a 16-bit char character. If cp is in the larger range then there is guaranteed to be another - character following the one located at index, which is the rest of the unicode character. */ protected @IndexOrHigh("#1") int nextEscapeIndex(CharSequence csq, @IndexOrHigh("#1") int start, @IndexOrHigh("#1") int end) { @IndexOrHigh("#1") int index = start; while (index < end) { @@ -163,18 +160,6 @@ public String escape(String string) { * @throws NullPointerException if {@code string} is null * @throws IllegalArgumentException if invalid surrogate characters are encountered */ - @SuppressWarnings(value = {"upperbound:compound.assignment.type.incompatible",/* - (1): `destIndex` is always @LTEqLengthOf("dest") @LessThan("destSize + 1") because `dest` array - will always be regrow when `destSize` is less than `sizeNeeded` */ - "upperbound:argument.type.incompatible",/* - (2): Because of System.arraycopy() method, `escaped.length` is required to be - @LTLengthOf(value={"escaped", "dest"}, offset={"-1", "destIndex - 1"}). - `escaped.length + destIndex - 1 < dest.length` is true because when `dest.length < sizeNeeded`, - `dest.length` regrow to new `destLength = destIndex + charsSkipped + escaped.length + (end - index) + DEST_PAD` - Since escaped.length is length of `escaped`, it should already be inferred to have length of @LTLengthOf(value="escaped", offset="-1") */ - "upperbound:assignment.type.incompatible"/* (3): In char arrays and CharSequence and its subclasses, two chars are used to represent - unicode characters that are outside the range of a 16-bit char character. If cp is in the larger range then there is guaranteed to be another - character following the one located at index, which is the rest of the unicode character. */}) protected final String escapeSlow(String s, @IndexOrHigh("#1") int index) { int end = s.length(); @@ -263,8 +248,6 @@ protected final String escapeSlow(String s, @IndexOrHigh("#1") int index) { * @return the Unicode code point for the given index or the negated value of the trailing high * surrogate character at the end of the sequence */ - @SuppressWarnings("upperbound:argument.type.incompatible")/* highest possible `end` value is `seq.length`, - `indexInternal` can't be >= seq.length in while loop.*/ protected static int codePointAt(CharSequence seq, @IndexFor("#1") int index, @IndexOrHigh("#1") int end) { checkNotNull(seq); @IndexOrHigh("seq") int indexInternal = index; @@ -313,8 +296,6 @@ protected static int codePointAt(CharSequence seq, @IndexFor("#1") int index, @I * Helper method to grow the character buffer as needed, this only happens once in a while so it's * ok if it's in a method call. If the index passed in is 0 then no copying will be done. */ - @SuppressWarnings("upperbound:argument.type.incompatible")//upper bound checker does not infer size - //as size of the array. Issue: https://github.com/typetools/checker-framework/issues/2029 private static char[] growBuffer(char[] dest, @LTEqLengthOf("#1") @LessThan("#3 + 1") int index, int size) { if (size < 0) { // overflow - should be OutOfMemoryError but GWT/j2cl don't support it throw new AssertionError("Cannot increase internal buffer any further"); diff --git a/guava/src/com/google/common/graph/DirectedGraphConnections.java b/guava/src/com/google/common/graph/DirectedGraphConnections.java index 3838bcfe8b74..ac5d08961a20 100644 --- a/guava/src/com/google/common/graph/DirectedGraphConnections.java +++ b/guava/src/com/google/common/graph/DirectedGraphConnections.java @@ -133,7 +133,7 @@ public int hashCode() { * LinkedHashMap combines two such edges into a single node-value pair, even though the edges may * not have been inserted consecutively. */ - @Nullable private final List> orderedNodeConnections; + private final @Nullable List> orderedNodeConnections; private int predecessorCount; private int successorCount; diff --git a/guava/src/com/google/common/graph/Traverser.java b/guava/src/com/google/common/graph/Traverser.java index be0eecb5f6fd..b5e674950e5b 100644 --- a/guava/src/com/google/common/graph/Traverser.java +++ b/guava/src/com/google/common/graph/Traverser.java @@ -478,8 +478,7 @@ protected N computeNext() { * into {@code horizon} between calls to {@code visitNext()}. This causes them to receive * additional values interleaved with those shown above.) */ - @Nullable - abstract N visitNext(Deque> horizon); + abstract @Nullable N visitNext(Deque> horizon); } /** Poor man's method reference for {@code Deque::addFirst} and {@code Deque::addLast}. */ diff --git a/guava/src/com/google/common/hash/AbstractHasher.java b/guava/src/com/google/common/hash/AbstractHasher.java index 16e1b04ca948..8d658827c243 100644 --- a/guava/src/com/google/common/hash/AbstractHasher.java +++ b/guava/src/com/google/common/hash/AbstractHasher.java @@ -53,15 +53,12 @@ public Hasher putUnencodedChars(CharSequence charSequence) { return this; } - @SuppressWarnings("argument.type.incompatible")//Strings#getBytes() should be annotated as @PolyValue @Override + @SuppressWarnings("value:argument") // Strings#getBytes() should be annotated as @PolyValue public Hasher putString(@MinLen(1) CharSequence charSequence, Charset charset) { return putBytes(charSequence.toString().getBytes(charset)); } - @SuppressWarnings("upperbound:argument.type.incompatible")/* `off` is required to be @LTLengthOf(value = "#1", offset = "len - 1"). Since `bytes.length` min value is 1, - `off = 0` + `bytes.length = 1" - 1 is still less than `bytes.length` - */ @Override public Hasher putBytes(byte @MinLen(1)[] bytes) { return putBytes(bytes, 0, bytes.length); @@ -77,8 +74,6 @@ public Hasher putBytes(byte[] bytes, @NonNegative @LTLengthOf(value = "#1", offs } @Override - @SuppressWarnings({"lowerbound:argument.type.incompatible" // b.arrayOffset(), b.position() and b.remaining() all return non negative values. - }) public Hasher putBytes(ByteBuffer b) { if (b.hasArray()) { putBytes(b.array(), b.arrayOffset() + b.position(), b.remaining()); @@ -108,6 +103,7 @@ public Hasher putInt(int i) { } @Override + @SuppressWarnings("signedness:shift.unsigned") public Hasher putLong(long l) { for (int i = 0; i < 64; i += 8) { putByte((byte) (l >>> i)); @@ -116,6 +112,7 @@ public Hasher putLong(long l) { } @Override + @SuppressWarnings("signedness:argument") public Hasher putChar(char c) { putByte((byte) c); putByte((byte) (c >>> 8)); diff --git a/guava/src/com/google/common/hash/AbstractNonStreamingHashFunction.java b/guava/src/com/google/common/hash/AbstractNonStreamingHashFunction.java index 6d383622b89f..80af6d3ed278 100644 --- a/guava/src/com/google/common/hash/AbstractNonStreamingHashFunction.java +++ b/guava/src/com/google/common/hash/AbstractNonStreamingHashFunction.java @@ -46,7 +46,7 @@ public Hasher newHasher(@NonNegative int expectedInputSize) { return new BufferingHasher(expectedInputSize); } - @SuppressWarnings("value:argument.type.incompatible")/* Since ByteBuffer is a mutable length data structure, `ByteBuffer.allocate(4)` + @SuppressWarnings("value:argument") /* Since ByteBuffer is a mutable length data structure, `ByteBuffer.allocate(4)` returns the new byte buffer with 4 as capacity, therefore `ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(input).array()` returns an array of length 4 */ @Override @@ -54,7 +54,7 @@ public HashCode hashInt(int input) { return hashBytes(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(input).array()); } - @SuppressWarnings("value:argument.type.incompatible")/* Since ByteBuffer is a mutable length data structure, `ByteBuffer.allocate(8)` + @SuppressWarnings("value:argument") /* Since ByteBuffer is a mutable length data structure, `ByteBuffer.allocate(8)` returns the new byte buffer with 8 as capacity, therefore `ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(input).array()` returns an array of length 8 */ @Override @@ -62,7 +62,7 @@ public HashCode hashLong(long input) { return hashBytes(ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(input).array()); } - @SuppressWarnings("value:argument.type.incompatible") /* Since ByteBuffer is a mutable length data structure and input + @SuppressWarnings("value:argument") /* Since ByteBuffer is a mutable length data structure and input has min length of 1,`ByteBuffer.allocate(len * 2)` returns the new byte buffer with min length of 2 as capacity, therefore ByteBuffer.allocate(len * 2).order(ByteOrder.LITTLE_ENDIAN) returns an array of non negative length */ @Override @@ -75,7 +75,7 @@ public HashCode hashUnencodedChars(@MinLen(1) CharSequence input) { return hashBytes(buffer.array()); } - @SuppressWarnings("value:argument.type.incompatible")//If `input` has min of 1, since `getBytes(charset)` + @SuppressWarnings("value:argument") //If `input` has min of 1, since `getBytes(charset)` // the resultant byte array, the array returned also has min length of 1 @Override public HashCode hashString(@MinLen(1) CharSequence input, Charset charset) { @@ -146,7 +146,7 @@ void write(ByteBuffer input) { count += remaining; } - @SuppressWarnings("value:return.type.incompatible")//`buf` array in the pre-compiled class `ByteArrayOutputStream` + @SuppressWarnings("value:return") //`buf` array in the pre-compiled class `ByteArrayOutputStream` // should be annotated as @MinLen(1) byte @MinLen(1)[] byteArray() { return buf; diff --git a/guava/src/com/google/common/hash/FarmHashFingerprint64.java b/guava/src/com/google/common/hash/FarmHashFingerprint64.java index 14cdd90ceaad..c36f72c9bc61 100644 --- a/guava/src/com/google/common/hash/FarmHashFingerprint64.java +++ b/guava/src/com/google/common/hash/FarmHashFingerprint64.java @@ -84,10 +84,12 @@ static long fingerprint(byte[] bytes, @NonNegative @LTLengthOf(value = "#1", off } } + @SuppressWarnings("signedness:shift.unsigned") private static long shiftMix(long val) { return val ^ (val >>> 47); } + @SuppressWarnings("signedness:shift.unsigned") private static long hashLength16(long u, long v, long mul) { long a = (u ^ v) * mul; a ^= (a >>> 47); @@ -119,12 +121,6 @@ private static void weakHashLength32WithSeeds( output[1] = seedB + c; } - @SuppressWarnings({"lowerbound:argument.type.incompatible",//(1): if length >= 8 and offset is non negative, offset + length - 8 >= 0. - "upperbound:argument.type.incompatible",//(2): if length >= 4 and offset + length - 1 < bytes.length, offset + 4 - 1 < bytes.length. - "upperbound:array.access.unsafe.high",/*(3): if 0 < length < 4, therefore offset + length - 1 < bytes.length, - offset + length / 2(length >> 2) - 1 < bytes.length and offset + length - 1 - 1 < bytes.length. - */ - }) private static long hashLength0to16(byte[] bytes, @NonNegative @LTLengthOf(value = "#1", offset = "#3 - 1") int offset, @IntRange(from = 0, to = 16) @LTLengthOf(value = "#1", offset = "#2 - 1") int length) { if (length >= 8) { long mul = K2 + length * 2; @@ -150,9 +146,6 @@ private static long hashLength0to16(byte[] bytes, @NonNegative @LTLengthOf(value return K2; } - @SuppressWarnings(value = {"lowerbound:argument.type.incompatible"/*(1): if 17 <= length <= 32 and offset is non negative, - offset + length - 8 >= 0 and offset + length - 16 >= 0. - */}) private static long hashLength17to32(byte[] bytes, @NonNegative @LTLengthOf(value = "#1", offset = "#3 - 1") int offset, @IntRange(from = 17, to = 32) @LTLengthOf(value = "#1", offset = "#2 - 1") int length) { long mul = K2 + length * 2; long a = load64(bytes, offset) * K1; @@ -182,13 +175,6 @@ private static long hashLength33To64(byte[] bytes, @NonNegative @LTLengthOf(val /* * Compute an 8-byte hash of a byte array of length greater than 64 bytes. */ - @SuppressWarnings({"lowerbound:assignment.type.incompatible",/*(1): since length >= 65, `end` is non negative, - therefore `last64offset` is also non negative. */ - "upperbound:assignment.type.incompatible",//(1): ? - "upperbound:compound.assignment.type.incompatible"/*(2): if length >= 65 and offset < bytes.length - length + 1, - offset += 64 < bytes.length. - */ - }) private static long hashLength65Plus(byte[] bytes, @NonNegative @LTLengthOf(value = "#1", offset = "#3 - 1") int offset, @IntRange(from = 65) @LTLengthOf(value = "#1", offset = "#2 - 1") int length) { final int seed = 81; // For strings over 64 bytes we loop. Internal state consists of 56 bytes: v, w, x, y, and z. diff --git a/guava/src/com/google/common/hash/Funnels.java b/guava/src/com/google/common/hash/Funnels.java index 157a821721d6..75691d8ebbc3 100644 --- a/guava/src/com/google/common/hash/Funnels.java +++ b/guava/src/com/google/common/hash/Funnels.java @@ -22,6 +22,7 @@ import org.checkerframework.checker.index.qual.LTLengthOf; import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.common.value.qual.MinLen; /** @@ -43,7 +44,7 @@ private enum ByteArrayFunnel implements Funnel { INSTANCE; @Override - public void funnel(byte @MinLen(1)[] from, PrimitiveSink into) { + public void funnel(byte [] from, PrimitiveSink into) { into.putBytes(from); } @@ -68,7 +69,7 @@ private enum UnencodedCharsFunnel implements Funnel { INSTANCE; @Override - public void funnel(@MinLen(1) CharSequence from, PrimitiveSink into) { + public void funnel(CharSequence from, PrimitiveSink into) { into.putUnencodedChars(from); } @@ -96,7 +97,7 @@ private static class StringCharsetFunnel implements Funnel, Serial } @Override - public void funnel(@MinLen(1) CharSequence from, PrimitiveSink into) { + public void funnel(CharSequence from, PrimitiveSink into) { into.putString(from, charset); } @@ -250,18 +251,18 @@ private static class SinkAsStream extends OutputStream { } @Override - public void write(int b) { + public void write(@PolySigned int b) { sink.putByte((byte) b); } - @SuppressWarnings("override.param.invalid")//OutputStream#write() should be annotated as void write(byte @MinLen(1)[] bytes) + @SuppressWarnings("override.param") // OutputStream#write() should be annotated as void write(byte @MinLen(1)[] bytes) @Override public void write(byte @MinLen(1)[] bytes) { sink.putBytes(bytes); } @Override - public void write(byte[] bytes, @NonNegative @LTLengthOf(value = "#1", offset = "#3 - 1") int off, @NonNegative @LTLengthOf(value = "#1", offset = "#2 - 1") int len) { + public void write(@PolySigned byte[] bytes, @NonNegative @LTLengthOf(value = "#1", offset = "#3 - 1") int off, @NonNegative @LTLengthOf(value = "#1", offset = "#2 - 1") int len) { sink.putBytes(bytes, off, len); } diff --git a/guava/src/com/google/common/hash/HashCode.java b/guava/src/com/google/common/hash/HashCode.java index 99a6b64d6c11..c968589957f3 100644 --- a/guava/src/com/google/common/hash/HashCode.java +++ b/guava/src/com/google/common/hash/HashCode.java @@ -256,6 +256,7 @@ public static HashCode fromBytes(byte @MinLen(1)[] bytes) { * must be handed-off so as to preserve the immutability contract of {@code HashCode}. */ static HashCode fromBytesNoCopy(byte @MinLen(1)[] bytes) { + checkArgument(bytes.length >= 1, "A HashCode must contain at least 1 byte."); return new BytesHashCode(bytes); } @@ -347,12 +348,7 @@ boolean equalsSameBits(HashCode that) { * * @since 15.0 */ - @SuppressWarnings({"upperbound:argument.type.incompatible",/* (1): `string` min length is 2 and `string.length` must be a even number. - Since for loop increment by two each iteration, `i` is always < `string.length - 2` */ - "upperbound:array.access.unsafe.high",/* Since `bytes.length = string.length / 2` and `i` is incremented by 2, range 0 - string.length() - `i / 2` is safe as indexes. */ - "argument.type.incompatible"//(2) Since `string.length >= 2` and `bytes.length` init is `string.length / 2`, bytes has min length of 1. - }) + @SuppressWarnings("value:argument") // fromBytesNoCopy verfies bytes contains at least 1 byte public static HashCode fromString(String string) { checkArgument( string.length() >= 2, "input string (%s) must have at least 2 characters", string); diff --git a/guava/src/com/google/common/hash/Hashing.java b/guava/src/com/google/common/hash/Hashing.java index 1eb6c8674372..36dc19a784b1 100644 --- a/guava/src/com/google/common/hash/Hashing.java +++ b/guava/src/com/google/common/hash/Hashing.java @@ -516,7 +516,7 @@ public static int consistentHash(long input, int buckets) { * @throws IllegalArgumentException if {@code hashCodes} is empty, or the hash codes do not all * have the same bit length */ - @SuppressWarnings("value:argument.type.incompatible")// `hashCode.asBytes()` return an array with min length of 1. + @SuppressWarnings("value:argument")// `hashCode.asBytes()` return an array with min length of 1. //Since nextBytes.length is checked to have same bit length with resultBytes.length, resultBytes also needs min length of 1. public static HashCode combineOrdered(Iterable hashCodes) { Iterator iterator = hashCodes.iterator(); @@ -543,7 +543,7 @@ public static HashCode combineOrdered(Iterable hashCodes) { * @throws IllegalArgumentException if {@code hashCodes} is empty, or the hash codes do not all * have the same bit length */ - @SuppressWarnings("value:argument.type.incompatible")// `hashCode.asBytes()` return an array with min length of 1. + @SuppressWarnings("value:argument")// `hashCode.asBytes()` return an array with min length of 1. //Since nextBytes.length is checked to have same bit length with resultBytes.length, resultBytes also needs min length of 1. public static HashCode combineUnordered(Iterable hashCodes) { Iterator iterator = hashCodes.iterator(); @@ -561,6 +561,7 @@ public static HashCode combineUnordered(Iterable hashCodes) { } /** Checks that the passed argument is positive, and ceils it to a multiple of 32. */ + @SuppressWarnings("value:return")// code verifies positive and >= 32 static @IntRange(from=32) int checkPositiveAndMakeMultipleOf32(int bits) { checkArgument(bits > 0, "Number of bits must be positive"); return (bits + 31) & ~31; @@ -621,6 +622,7 @@ private ConcatenatedHashFunction(HashFunction... functions) { } @Override + @SuppressWarnings("value:argument") // fromBytesNoCopy verfies bytes contains at least 1 byte HashCode makeHash(Hasher[] hashers) { byte[] bytes = new byte[bits() / 8]; int i = 0; @@ -666,6 +668,7 @@ public LinearCongruentialGenerator(long seed) { this.state = seed; } + @SuppressWarnings("signedness:shift.unsigned") public double nextDouble() { state = 2862933555777941757L * state + 1; return ((double) ((int) (state >>> 33) + 1)) / 0x1.0p31; diff --git a/guava/src/com/google/common/hash/LongAdder.java b/guava/src/com/google/common/hash/LongAdder.java index 674ba4d29965..e47b7366694a 100644 --- a/guava/src/com/google/common/hash/LongAdder.java +++ b/guava/src/com/google/common/hash/LongAdder.java @@ -17,6 +17,7 @@ import java.io.Serializable; import java.util.concurrent.atomic.AtomicLong; import org.checkerframework.common.value.qual.MinLen; +import org.checkerframework.common.value.qual.PolyValue; /** * One or more variables that together maintain an initially zero {@code long} sum. When updates @@ -56,7 +57,7 @@ public LongAdder() {} * * @param x the value to add */ - @SuppressWarnings("value:assignment.type.incompatible")// if `threadHashCode.get()` return an array of min length < 1, + @SuppressWarnings("value:assignment") // if `threadHashCode.get()` return an array of min length < 1, // other conditions will be computed. @Override public void add(long x) { @@ -158,26 +159,30 @@ public String toString() { * @return the sum */ @Override - public long longValue() { - return sum(); + @SuppressWarnings("cast.unsafe") + public @PolyValue long longValue(@PolyValue LongAdder this) { + return (@PolyValue long)sum(); } /** Returns the {@link #sum} as an {@code int} after a narrowing primitive conversion. */ @Override - public int intValue() { - return (int) sum(); + @SuppressWarnings("cast.unsafe") + public @PolyValue int intValue(@PolyValue LongAdder this) { + return (@PolyValue int) sum(); } /** Returns the {@link #sum} as a {@code float} after a widening primitive conversion. */ @Override - public float floatValue() { - return (float) sum(); + @SuppressWarnings("cast.unsafe") + public @PolyValue float floatValue(@PolyValue LongAdder this) { + return (@PolyValue float) sum(); } /** Returns the {@link #sum} as a {@code double} after a widening primitive conversion. */ @Override - public double doubleValue() { - return (double) sum(); + @SuppressWarnings("cast.unsafe") + public @PolyValue double doubleValue(@PolyValue LongAdder this) { + return (@PolyValue double) sum(); } private void writeObject(ObjectOutputStream s) throws IOException { diff --git a/guava/src/com/google/common/hash/MessageDigestHashFunction.java b/guava/src/com/google/common/hash/MessageDigestHashFunction.java index 97c3a077c1cd..650d63948020 100644 --- a/guava/src/com/google/common/hash/MessageDigestHashFunction.java +++ b/guava/src/com/google/common/hash/MessageDigestHashFunction.java @@ -158,7 +158,7 @@ private void checkNotDone() { checkState(!done, "Cannot re-use a Hasher after calling hash() on it"); } - @SuppressWarnings("value:argument.type.incompatible")/* `bytes` is positive, if `digest.getDigestLength()` returns + @SuppressWarnings("value:argument") /* `bytes` is positive, if `digest.getDigestLength()` returns a positive and equals to `bytes`, `digest.digest()` returns array with min length of 1. */ @Override diff --git a/guava/src/com/google/common/hash/PrimitiveSink.java b/guava/src/com/google/common/hash/PrimitiveSink.java index 68122880e6a8..b737912c8f5a 100644 --- a/guava/src/com/google/common/hash/PrimitiveSink.java +++ b/guava/src/com/google/common/hash/PrimitiveSink.java @@ -47,7 +47,7 @@ public interface PrimitiveSink { * @param bytes a byte array * @return this instance */ - PrimitiveSink putBytes(byte[] bytes); + PrimitiveSink putBytes(byte @MinLen(1)[] bytes); /** * Puts a chunk of an array of bytes into this sink. {@code bytes[off]} is the first byte written, diff --git a/guava/src/com/google/common/io/BaseEncoding.java b/guava/src/com/google/common/io/BaseEncoding.java index c2a3a4674be5..4bb682503a77 100644 --- a/guava/src/com/google/common/io/BaseEncoding.java +++ b/guava/src/com/google/common/io/BaseEncoding.java @@ -40,6 +40,7 @@ import org.checkerframework.checker.index.qual.LTLengthOf; import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.common.value.qual.ArrayLen; import org.checkerframework.common.value.qual.MinLen; @@ -434,8 +435,6 @@ private static final class Alphabet { private final byte[] decodabet; private final boolean[] validPadding; - @SuppressWarnings({"array.access.unsafe", "assignment.type.incompatible"}) /* c will be a valid index by the time decodabet is accessed with it. validPadding has - enough space because the loop stops when i = bytesPerChunk. chars is the same as this.chars, so the assignment of this.mask is safe.*/ Alphabet(String name, char @MinLen(1) [] chars) { this.name = checkNotNull(name); this.chars = checkNotNull(chars); @@ -449,7 +448,6 @@ private static final class Alphabet { * e.g. for base64, bitsPerChar == 6, charsPerChunk == 4, and bytesPerChunk == 3. This makes * for the smallest chunk size that still has charsPerChunk * bitsPerChar be a multiple of 8. */ - @SuppressWarnings("assignment.type.incompatible") // lowestOneBit cannot return a value with first bit 1 when the value is non-negative @NonNegative int gcd = Math.min(8, Integer.lowestOneBit(bitsPerChar)); try { this.charsPerChunk = 8 / gcd; @@ -481,12 +479,10 @@ char encode(@IndexFor("this.chars") int bits) { return chars[bits]; } - @SuppressWarnings("array.access.unsafe") // The index used is smaller than charsPerChunk, which is the length of validPadding boolean isValidPaddingStartPosition(@NonNegative int index) { return validPadding[index % charsPerChunk]; } - @SuppressWarnings("array.access.unsafe") // decodabet won't be accessed with an invalid index because a char is greater than 0. boolean canDecode(char ch) { return ch <= Ascii.MAX && decodabet[ch] != -1; } @@ -548,7 +544,6 @@ Alphabet lowerCase() { return new Alphabet(name + ".lowerCase()", lowerCased); } - @SuppressWarnings("array.access.unsafe") // if c is not a valid index for decodabet, the second operand will not be processed. public boolean matches(char c) { return c < decodabet.length && decodabet[c] != -1; } @@ -593,7 +588,6 @@ static class StandardBaseEncoding extends BaseEncoding { } @Override - @SuppressWarnings("return.type.incompatible") // Every operand is non-negative @NonNegative int maxEncodedSize(@NonNegative int bytes) { return alphabet.charsPerChunk * divide(bytes, alphabet.bytesPerChunk, CEILING); } @@ -608,7 +602,7 @@ public OutputStream encodingStream(final Writer out) { int writtenChars = 0; @Override - public void write(int b) throws IOException { + public void write(@PolySigned int b) throws IOException { bitBuffer <<= 8; bitBuffer |= b & 0xFF; bitBufferLength += 8; @@ -644,7 +638,6 @@ public void close() throws IOException { } @Override - @SuppressWarnings("argument.type.incompatible") /* The offset and the length have been previously checked and the loop stops before the arguments become invalid*/ void encodeTo(Appendable target, byte[] bytes, @IndexOrHigh("#2") int off, @NonNegative @LTLengthOf(value = "#2", offset = "#3 - 1") int len) throws IOException { checkNotNull(target); checkPositionIndexes(off, off + len, bytes.length); @@ -679,7 +672,6 @@ void encodeChunkTo(Appendable target, byte[] bytes, @IndexOrHigh("#2") int off, } @Override - @SuppressWarnings("return.type.incompatible") // Every operand is non-negative @NonNegative int maxDecodedSize(@NonNegative int chars) { return (int) ((alphabet.bitsPerChar * (long) chars + 7L) / 8L); } @@ -716,8 +708,6 @@ public boolean canDecode(CharSequence chars) { } @Override - @SuppressWarnings({"argument.type.incompatible", "array.access.unsafe", "return.type.incompatible"}) - /* chars will not be accessed with an invalid index because of the loop stop condition. */ @IndexFor("#1") int decodeTo(byte[] target, CharSequence chars) throws DecodingException { checkNotNull(target); chars = trimTrailingPadding(chars); @@ -910,9 +900,6 @@ static final class Base16Encoding extends StandardBaseEncoding { this(new Alphabet(name, alphabetChars.toCharArray())); } - @SuppressWarnings({"array.access.unsafe", "argument.type.incompatible"}) /* Since encoding has a length of 512, it is safe to - access it with indexes from 0 to 255 and 256 to 511, respectively. The calls to encode are safe because it has been previously - verified that the length of chars array is exactly 16*/ private Base16Encoding(Alphabet alphabet) { super(alphabet, null); checkArgument(alphabet.chars.length == 16); @@ -923,7 +910,6 @@ private Base16Encoding(Alphabet alphabet) { } @Override - @SuppressWarnings("array.access.unsafe") // encoding has length 512, so it can be accessed with b + 256 void encodeTo(Appendable target, byte[] bytes, @IndexOrHigh("#2") int off, @NonNegative @LTLengthOf(value = "#2", offset = "#3 - 1") int len) throws IOException { checkNotNull(target); checkPositionIndexes(off, off + len, bytes.length); @@ -935,8 +921,6 @@ void encodeTo(Appendable target, byte[] bytes, @IndexOrHigh("#2") int off, @NonN } @Override - @SuppressWarnings({"return.type.incompatible", "array.access.unsafe"}) /* bytesWritten grows slower than i, which stops - when it exceeds the length of target */ @IndexFor("#1") int decodeTo(byte[] target, CharSequence chars) throws DecodingException { checkNotNull(target); if (chars.length() % 2 == 1) { @@ -944,7 +928,6 @@ void encodeTo(Appendable target, byte[] bytes, @IndexOrHigh("#2") int off, @NonN } int bytesWritten = 0; for (int i = 0; i < chars.length(); i += 2) { - @SuppressWarnings("argument.type.incompatible") // a char variable is a valid index for chars. int decoded = alphabet.decode(chars.charAt(i)) << 4 | alphabet.decode(chars.charAt(i + 1)); target[bytesWritten++] = (byte) decoded; } @@ -968,14 +951,11 @@ private Base64Encoding(Alphabet alphabet, @Nullable Character paddingChar) { } @Override - @SuppressWarnings("argument.type.incompatible") /* i is between off and off + len, so the last method call is safe. - alphabet.chars has length 64, all arguments of encode() are 6-bits long */ void encodeTo(Appendable target, byte[] bytes, @IndexOrHigh("#2") int off, @NonNegative @LTLengthOf(value = "#2", offset = "#3 - 1") int len) throws IOException { checkNotNull(target); checkPositionIndexes(off, off + len, bytes.length); int i = off; for (int remaining = len; remaining >= 3; remaining -= 3) { - @SuppressWarnings("array.access.unsafe") // i is a valid index because the parameters have been checked int chunk = (bytes[i++] & 0xFF) << 16 | (bytes[i++] & 0xFF) << 8 | bytes[i++] & 0xFF; target.append(alphabet.encode(chunk >>> 18)); target.append(alphabet.encode((chunk >>> 12) & 0x3F)); @@ -988,9 +968,6 @@ void encodeTo(Appendable target, byte[] bytes, @IndexOrHigh("#2") int off, @NonN } @Override - @SuppressWarnings({"argument.type.incompatible", "array.access.unsafe", "return.type.incompatible"}) - /* i will be a valid index for chars because it is verified at every step. charAt() returns a char value, which is known to be - a valid index for alphabet. bytesWritten grows just like variable i, so it will not exceed the length of chars. */ @IndexFor("#1") int decodeTo(byte[] target, CharSequence chars) throws DecodingException { checkNotNull(target); chars = trimTrailingPadding(chars); @@ -1084,6 +1061,7 @@ static Writer separatingWriter( separatingAppendable(delegate, separator, afterEveryChars); return new Writer() { @Override + @SuppressWarnings("signedness:cast.unsafe") // can't prove c fits in a char??? public void write(int c) throws IOException { separatingAppendable.append((char) c); } @@ -1124,7 +1102,6 @@ CharSequence trimTrailingPadding(CharSequence chars) { } @Override - @SuppressWarnings("return.type.incompatible") // Every operand in the return expression is non-negative @NonNegative int maxEncodedSize(@NonNegative int bytes) { int unseparatedSize = delegate.maxEncodedSize(bytes); return unseparatedSize diff --git a/guava/src/com/google/common/io/ByteSource.java b/guava/src/com/google/common/io/ByteSource.java index 330860d27966..bb9e171e3b42 100644 --- a/guava/src/com/google/common/io/ByteSource.java +++ b/guava/src/com/google/common/io/ByteSource.java @@ -544,7 +544,7 @@ public boolean isEmpty() throws IOException { } @Override - @SuppressWarnings("return.type.incompatible") // off is at most equal to unslicedSize and length is non-negative + @SuppressWarnings("value:return") // off is at most equal to unslicedSize and length is non-negative public Optional<@NonNegative Long> sizeIfKnown() { Optional<@NonNegative Long> optionalUnslicedSize = ByteSource.this.sizeIfKnown(); if (optionalUnslicedSize.isPresent()) { @@ -571,8 +571,6 @@ private static class ByteArrayByteSource extends ByteSource { this(bytes, 0, bytes.length); } - // NOTE: Preconditions are enforced by slice, the only non-trivial caller. - @SuppressWarnings("assignment.type.incompatible") /* bytes is the same as this.bytes, and offset is the same as this.offset */ ByteArrayByteSource(byte[] bytes, @IndexOrHigh("#1") int offset, @NonNegative @LTLengthOf(value = "#1", offset = "#2 - 1") int length) { this.bytes = bytes; this.offset = offset; @@ -628,8 +626,6 @@ public HashCode hash(HashFunction hashFunction) throws IOException { } @Override - @SuppressWarnings({"assignment.type.incompatible", "argument.type.incompatible"}) /* length is valid because offset - is smaller than the this.length */ public ByteSource slice(@NonNegative long offset, @NonNegative long length) { checkArgument(offset >= 0, "offset (%s) may not be negative", offset); checkArgument(length >= 0, "length (%s) may not be negative", length); @@ -697,7 +693,7 @@ public boolean isEmpty() throws IOException { } @Override - @SuppressWarnings("return.type.incompatible") // Long.MAX_VALUE is non-negative + @SuppressWarnings("value:return") // Long.MAX_VALUE is non-negative public Optional<@NonNegative Long> sizeIfKnown() { if (!(sources instanceof Collection)) { // Infinite Iterables can cause problems here. Of course, it's true that most of the other diff --git a/guava/src/com/google/common/io/ByteStreams.java b/guava/src/com/google/common/io/ByteStreams.java index 201b6323c3cc..9809a873d660 100644 --- a/guava/src/com/google/common/io/ByteStreams.java +++ b/guava/src/com/google/common/io/ByteStreams.java @@ -47,6 +47,7 @@ import org.checkerframework.checker.index.qual.LTLengthOf; import org.checkerframework.checker.index.qual.LessThan; import org.checkerframework.checker.index.qual.NonNegative; +import org.checkerframework.checker.signedness.qual.PolySigned; import java.util.Deque; import java.util.Queue; @@ -204,8 +205,6 @@ private static byte[] toByteArrayInternal(InputStream in, Queue bufs, @N } } - @SuppressWarnings("argument.type.incompatible") /* resultOffset is greater than 0 because remaining gets closer to 0 - totalLen stays the same. bytesToCopy is valid because it can't exceed the length of buf */ private static byte[] combineBuffers(Queue bufs, @NonNegative int totalLen) { byte[] result = new byte[totalLen]; int remaining = totalLen; @@ -246,10 +245,7 @@ static byte[] toByteArray(InputStream in, @NonNegative long expectedSize) throws @LessThan("expectedSize + 1") int remaining = (int) expectedSize; while (remaining > 0) { - @SuppressWarnings("assignment.type.incompatible") /* off can't go below 0 because remaining doesn't get bigger, - only smaller. It can't go beyond an index for bytes because the loop stops when remaining is negative */ @IndexOrHigh("bytes") int off = (int) expectedSize - remaining; - @SuppressWarnings("argument.type.incompatible") /* off + remaining is at most expectedSize, which is the size of bytes. */ int read = in.read(bytes, off, remaining); if (read == -1) { // end of stream before reading expectedSize bytes @@ -307,8 +303,6 @@ public static ByteArrayDataInput newDataInput(byte[] bytes) { * the array */ @Beta - @SuppressWarnings("argument.type.incompatible") /* bytes.length - start is a correct length for the array because start - is smaller than bytes.length and it doesn't exceed bytes.length when start is added as offset.*/ public static ByteArrayDataInput newDataInput(byte[] bytes, @IndexOrHigh("#1") int start) { checkPositionIndex(start, bytes.length); return newDataInput(new ByteArrayInputStream(bytes, start, bytes.length - start)); @@ -656,17 +650,17 @@ public byte[] toByteArray() { new OutputStream() { /** Discards the specified byte. */ @Override - public void write(int b) {} + public void write(@PolySigned int b) {} /** Discards the specified byte array. */ @Override - public void write(byte[] b) { + public void write(@PolySigned byte[] b) { checkNotNull(b); } /** Discards the specified byte array. */ @Override - public void write(byte[] b, @IndexOrHigh("#1") int off, @NonNegative @LTLengthOf(value = "#1", offset = "#2 - 1") int len) { + public void write(@PolySigned byte[] b, @IndexOrHigh("#1") int off, @NonNegative @LTLengthOf(value = "#1", offset = "#2 - 1") int len) { checkNotNull(b); } @@ -724,7 +718,6 @@ public synchronized void mark(@NonNegative int readLimit) { } @Override - @SuppressWarnings("compound.assignment.type.incompatible") /* left can't go below 0 because it was previously checked*/ public @GTENegativeOne int read() throws IOException { if (left == 0) { return -1; @@ -752,7 +745,6 @@ public synchronized void mark(@NonNegative int readLimit) { } @Override - @SuppressWarnings("assignment.type.incompatible") /* mark is surely non-negative because of the check before*/ public synchronized void reset() throws IOException { if (!in.markSupported()) { throw new IOException("Mark not supported"); @@ -935,8 +927,6 @@ public static int read(InputStream in, byte[] b, @IndexOrHigh("#2") int off, @No checkPositionIndexes(off, off + len, b.length); int total = 0; while (total < len) { - @SuppressWarnings("argument.type.incompatible") /* if the offset and length passed to this method are invalid, - an exception would be thrown anyways, so there is no need to check them before */ int result = in.read(b, off + total, len - total); if (result == -1) { break; diff --git a/guava/src/com/google/common/io/FileBackedOutputStream.java b/guava/src/com/google/common/io/FileBackedOutputStream.java index ab687adb180c..51a6a04e2939 100644 --- a/guava/src/com/google/common/io/FileBackedOutputStream.java +++ b/guava/src/com/google/common/io/FileBackedOutputStream.java @@ -58,7 +58,7 @@ public final class FileBackedOutputStream extends OutputStream { private final int fileThreshold; private final boolean resetOnFinalize; private final ByteSource source; - @Nullable private final File parentDirectory; + private final @Nullable File parentDirectory; @GuardedBy("this") private OutputStream out; @@ -75,7 +75,6 @@ byte[] getBuffer() { return buf; } - @SuppressWarnings("return.type.incompatible") // this.getBuffer() is the same as this.buf @IndexOrHigh("this.getBuffer()") int getCount() { return count; } diff --git a/guava/src/com/google/common/math/LongMath.java b/guava/src/com/google/common/math/LongMath.java index aea5f914337a..d80056ce6af0 100644 --- a/guava/src/com/google/common/math/LongMath.java +++ b/guava/src/com/google/common/math/LongMath.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.index.qual.LTLengthOf; import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.Positive; +import org.checkerframework.checker.signedness.qual.Unsigned; import org.checkerframework.common.value.qual.IntRange; import org.checkerframework.common.value.qual.MinLen; @@ -110,9 +111,7 @@ public static boolean isPowerOfTwo(long x) { * signed long. The implementation is branch-free, and benchmarks suggest it is measurably faster * than the straightforward ternary expression. */ - @SuppressWarnings("value:return.type.incompatible")/* An int has 64 bits, the lestmost bit is 0 for positive values, and is 1 for negative values. - For shift right zero fill operator( >>> ), the left operands value is moved right by the number of bits specified by the right operand - and shifted values are filled up with zeros. Therefore if x > y, (x - y) return a positive value, when being shifted 63 bits, it returns 0, otherwise return 1. */ + @SuppressWarnings("signedness:shift.unsigned") @VisibleForTesting static @IntRange(from = 0, to = 1) int lessThanBranchFree(long x, long y) { // Returns the sign bit of x - y. @@ -147,6 +146,7 @@ public static int log2(long x, RoundingMode mode) { case HALF_EVEN: // Since sqrt(2) is irrational, log2(x) - logFloor cannot be exactly 0.5 int leadingZeros = Long.numberOfLeadingZeros(x); + @SuppressWarnings("signedness:shift.unsigned") long cmp = MAX_POWER_OF_SQRT2_UNSIGNED >>> leadingZeros; // floor(2^(logFloor + 0.5)) int logFloor = (Long.SIZE - 1) - leadingZeros; @@ -195,20 +195,6 @@ public static int log10(@Positive long x, RoundingMode mode) { } @GwtIncompatible // TODO - @SuppressWarnings(value = {"lowerbound:return.type.incompatible",/* (2): `log10Floor()` returns a negative value if y is 0 and - `lessThanBranchFree(x, powersOf10[y])` returns 1( when x < powersOf10[y]). Since x is positive, y is 0 when 0 < x < 8( the array `maxLog10ForLeadingZeros` has 0 values at indexes: 61, 62, 63). - Since when 0 < x < 8, y is 0 and powersOf10[0] is 1, x can't be < `powersOf10[y]`, therefore `log10Floor()` won't return - a negative value. */ - "upperbound:return.type.incompatible",/*(2) powersOf10.length is 19 and largest element in `maxLog10ForLeadingZeros` is 19 at index 0. - Since `log10Floor()` is a static method and only called by methods that take in positive `x` values, `Long.numberOfLeadingZeros(x)` - won't return 0 and cause an error */ - "upperbound:assignment.type.incompatible",/*(2): except for element at index 0 in `maxLog10ForLeadingZeros`, the rest - can be indexed for `powersOf10` */ - "upperbound:array.access.unsafe.high.range"/*(1): `Long.numberOfLeadingZeros(x)` can return an int range from 0 to 64, - therfore the array `maxLog10ForLeadingZeros` should have min length of 65. However, since param `x` is required to - be positive, the highest int from `Long.numberOfLeadingZeros(x)` is 63. - */ - }) static @IndexFor(value = {"powersOf10", "halfPowersOf10"}) int log10Floor(@Positive long x) { /* * Based on Hacker's Delight Fig. 11-5, the two-table-lookup, branch-free implementation. @@ -289,7 +275,6 @@ public static int log10(@Positive long x, RoundingMode mode) { * * @throws IllegalArgumentException if {@code k < 0} */ - @SuppressWarnings("index") // https://github.com/typetools/checker-framework/issues/2541 @GwtIncompatible // TODO public static long pow(long b, int k) { checkNonNegative("exponent", k); @@ -624,7 +609,6 @@ public static long checkedMultiply(long a, long b) { * @throws ArithmeticException if {@code b} to the {@code k}th power overflows in signed {@code * long} arithmetic */ - @SuppressWarnings("index") // https://github.com/typetools/checker-framework/issues/2541 @GwtIncompatible // TODO public static long checkedPow(long b, int k) { checkNonNegative("exponent", k); @@ -674,6 +658,7 @@ public static long checkedPow(long b, int k) { * @since 20.0 */ @Beta + @SuppressWarnings("signedness:shift.unsigned") public static long saturatedAdd(long a, long b) { long naiveSum = a + b; if ((a ^ b) < 0 | (a ^ naiveSum) >= 0) { @@ -692,6 +677,7 @@ public static long saturatedAdd(long a, long b) { * @since 20.0 */ @Beta + @SuppressWarnings("signedness:shift.unsigned") public static long saturatedSubtract(long a, long b) { long naiveDifference = a - b; if ((a ^ b) >= 0 | (a ^ naiveDifference) >= 0) { @@ -721,6 +707,7 @@ public static long saturatedMultiply(long a, long b) { return a * b; } // the return value if we will overflow (which we calculate by overflowing a long :) ) + @SuppressWarnings("signedness:shift.unsigned") long limit = Long.MAX_VALUE + ((a ^ b) >>> (Long.SIZE - 1)); if (leadingZeros < Long.SIZE | (a < 0 & b == Long.MIN_VALUE)) { // overflow @@ -739,7 +726,6 @@ public static long saturatedMultiply(long a, long b) { * * @since 20.0 */ - @SuppressWarnings("index") // https://github.com/typetools/checker-framework/issues/2541 @Beta public static long saturatedPow(long b, int k) { checkNonNegative("exponent", k); @@ -767,6 +753,7 @@ public static long saturatedPow(long b, int k) { } long accum = 1; // if b is negative and k is odd then the limit is MIN otherwise the limit is MAX + @SuppressWarnings("signedness:shift.unsigned") long limit = Long.MAX_VALUE + ((b >>> Long.SIZE - 1) & (k & 1)); while (true) { switch (k) { @@ -833,9 +820,6 @@ public static long factorial(@NonNegative int n) { * * @throws IllegalArgumentException if {@code n < 0}, {@code k < 0}, or {@code k > n} */ - @SuppressWarnings({"lowerbound:unary.decrement.type.incompatible", // k = n - k is non-negative - "array.access.unsafe.low" // looks like a bug, possibly related to the above - }) public static long binomial(@NonNegative @LTLengthOf("this.factorials") int n, @NonNegative @LessThan("#1 + 1") int k) { checkNonNegative("n", n); checkNonNegative("k", k); @@ -1070,7 +1054,7 @@ public static boolean isPrime(long n) { return true; } - for (long[] baseSet : millerRabinBaseSets) { + for (@Unsigned long[] baseSet : millerRabinBaseSets) { if (n <= baseSet[0]) { for (int i = 1; i < baseSet.length; i++) { if (!MillerRabinTester.test(baseSet[i], n)) { @@ -1090,7 +1074,7 @@ public static boolean isPrime(long n) { * NOTE: We could get slightly better bases that would be treated as unsigned, but benchmarks * showed negligible performance improvements. */ - private static final long[] @MinLen(1)[] millerRabinBaseSets = { + private static final @Unsigned long[] @MinLen(1)[] millerRabinBaseSets = { {291830, 126401071349994536L}, {885594168, 725270293939359937L, 3569819667048198375L}, {273919523040L, 15, 7363882082L, 992620450144556L}, @@ -1119,7 +1103,7 @@ private enum MillerRabinTester { /** Works for inputs ≤ FLOOR_SQRT_MAX_LONG. */ SMALL { @Override - long mulMod(long a, long b, long m) { + @Unsigned long mulMod(@Unsigned long a, @Unsigned long b, @Unsigned long m) { /* * lowasser, 2015-Feb-12: Benchmarks suggest that changing this to UnsignedLongs.remainder * and increasing the threshold to 2^32 doesn't pay for itself, and adding another enum @@ -1130,19 +1114,19 @@ long mulMod(long a, long b, long m) { } @Override - long squareMod(long a, long m) { + @Unsigned long squareMod(@Unsigned long a, @Unsigned long m) { return (a * a) % m; } }, /** Works for all nonnegative signed longs. */ LARGE { /** Returns (a + b) mod m. Precondition: {@code 0 <= a}, {@code b < m < 2^63}. */ - private long plusMod(long a, long b, long m) { + private @Unsigned long plusMod(@Unsigned long a, @Unsigned long b, @Unsigned long m) { return (a >= m - b) ? (a + b - m) : (a + b); } /** Returns (a * 2^32) mod m. a may be any unsigned long. */ - private long times2ToThe32Mod(long a, long m) { + private @Unsigned long times2ToThe32Mod(@Unsigned long a, @Unsigned long m) { int remainingPowersOf2 = 32; do { int shift = Math.min(remainingPowersOf2, Long.numberOfLeadingZeros(a)); @@ -1155,7 +1139,7 @@ private long times2ToThe32Mod(long a, long m) { } @Override - long mulMod(long a, long b, long m) { + @Unsigned long mulMod(@Unsigned long a, @Unsigned long b, @Unsigned long m) { long aHi = a >>> 32; // < 2^31 long bHi = b >>> 32; // < 2^31 long aLo = a & 0xFFFFFFFFL; // < 2^32 @@ -1169,7 +1153,7 @@ long mulMod(long a, long b, long m) { * unsigned long, we don't have to do a mod on every operation, only when intermediate * results can exceed 2^63. */ - long result = times2ToThe32Mod(aHi * bHi /* < 2^62 */, m); // < m < 2^63 + @Unsigned long result = times2ToThe32Mod(aHi * bHi /* < 2^62 */, m); // < m < 2^63 result += aHi * bLo; // aHi * bLo < 2^63, result < 2^64 if (result < 0) { result = UnsignedLongs.remainder(result, m); @@ -1181,7 +1165,7 @@ long mulMod(long a, long b, long m) { } @Override - long squareMod(long a, long m) { + @Unsigned long squareMod(@Unsigned long a, @Unsigned long m) { long aHi = a >>> 32; // < 2^31 long aLo = a & 0xFFFFFFFFL; // < 2^32 @@ -1204,21 +1188,21 @@ long squareMod(long a, long m) { } }; - static boolean test(long base, long n) { + static boolean test(@Unsigned long base, @Unsigned long n) { // Since base will be considered % n, it's okay if base > FLOOR_SQRT_MAX_LONG, // so long as n <= FLOOR_SQRT_MAX_LONG. return ((n <= FLOOR_SQRT_MAX_LONG) ? SMALL : LARGE).testWitness(base, n); } /** Returns a * b mod m. */ - abstract long mulMod(long a, long b, long m); + abstract @Unsigned long mulMod(@Unsigned long a, @Unsigned long b, @Unsigned long m); /** Returns a^2 mod m. */ - abstract long squareMod(long a, long m); + abstract @Unsigned long squareMod(@Unsigned long a, @Unsigned long m); /** Returns a^p mod m. */ - private long powMod(long a, long p, long m) { - long res = 1; + private @Unsigned long powMod(@Unsigned long a, @Unsigned long p, @Unsigned long m) { + @Unsigned long res = 1; for (; p != 0; p >>= 1) { if ((p & 1) != 0) { res = mulMod(res, a, m); @@ -1229,7 +1213,7 @@ private long powMod(long a, long p, long m) { } /** Returns true if n is a strong probable prime relative to the specified base. */ - private boolean testWitness(long base, long n) { + private boolean testWitness(@Unsigned long base, @Unsigned long n) { int r = Long.numberOfTrailingZeros(n - 1); long d = (n - 1) >> r; base %= n; @@ -1237,7 +1221,7 @@ private boolean testWitness(long base, long n) { return true; } // Calculate a := base^d mod n. - long a = powMod(base, d, n); + @Unsigned long a = powMod(base, d, n); // n passes this test if // base^d = 1 (mod n) // or base^(2^j * d) = -1 (mod n) for some 0 <= j < r. diff --git a/guava/src/com/google/common/math/Quantiles.java b/guava/src/com/google/common/math/Quantiles.java index b05afa4b17c8..cd8a424443b3 100644 --- a/guava/src/com/google/common/math/Quantiles.java +++ b/guava/src/com/google/common/math/Quantiles.java @@ -207,7 +207,7 @@ public ScaleAndIndexes indexes(@NonNegative int @MinLen(1)... indexes) { * set will be snapshotted when this method is called * @throws IllegalArgumentException if {@code indexes} is empty */ - @SuppressWarnings({"value:argument.type.incompatible", "lowerbound:argument.type.incompatible"})//parameter `indexes` is of mutable length data structures(Collection) + @SuppressWarnings("value:argument") // parameter `indexes` is of mutable length data structures(Collection) public ScaleAndIndexes indexes(Collection indexes) { return new ScaleAndIndexes(scale, Ints.toArray(indexes)); } @@ -238,7 +238,7 @@ private ScaleAndIndex(@Positive int scale, @NonNegative int index) { * this call (it is copied instead) * @return the quantile value */ - @SuppressWarnings("value:argument.type.incompatible")// `dataset` is of mutable length data structures type( `Collection`) + @SuppressWarnings("value:argument") // `dataset` is of mutable length data structures type( `Collection`) //if `dataset` is not empty as specified in doc, method `Doubles.toArray()` return a non empty `dataset` as well public double compute(Collection dataset) { return computeInPlace(Doubles.toArray(dataset)); @@ -285,12 +285,6 @@ public double compute(int @MinLen(1)... dataset) { * be arbitrarily reordered by this method call * @return the quantile value */ - @SuppressWarnings({"lowerbound:assignment.type.incompatible",// (0): Since index and (dataset.length - 1) are non-negative ints, numerator is non negative. - "upperbound:argument.type.incompatible", "upperbound:array.access.unsafe.high",/* (1): second argument in selectInPlace() is `dataset`, - therefore `quotient + 1` should be < dataset.length. If remainder is not zero, - quotient max value is `dataset.length - 2`*/ - "upperbound:assignment.type.incompatible"/*(3) Since `numerator = index * (dataset.length - 1)`, - dividing it to scale will return a value less than dataset.length. */}) public double computeInPlace(double @MinLen(1)... dataset) { checkArgument(dataset.length > 0, "Cannot calculate quantiles of an empty dataset"); if (containsNaN(dataset)) { @@ -352,7 +346,7 @@ private ScaleAndIndexes(int scale, @NonNegative int @MinLen(1)[] indexes) { * indexes} method. */ - @SuppressWarnings("value:argument.type.incompatible")// `dataset` is of mutable length data structures type( `Collection`) + @SuppressWarnings("value:argument") // `dataset` is of mutable length data structures type( `Collection`) //if `dataset` is not empty as specified in doc, method `Doubles.toArray()` return a non empty `dataset` as well public Map compute(Collection dataset) { return computeInPlace(Doubles.toArray(dataset)); @@ -411,19 +405,6 @@ public Map compute(int @MinLen(1)... dataset) { * map are ordered by quantile index in the same order that the indexes were passed to the * {@code indexes} method. */ - @SuppressWarnings({"upperbound:compound.assignment.type.incompatible",/* (1): Since `requiredSelections.length = indexes.length * 2`, and the for loop - iterate from 0 to indexes.length, increment on requiredSelectionsCount is safe thoughout the loop. - */ - "lowerbound:argument.type.incompatible", "upperbound:argument.type.incompatible",/* (2): Since `indexes` is annotated to have at least length of 1, - `requiredSelections.length` will be at least 2, therefore larger than constant 0. */ - "lowerbound:assignment.type.incompatible",/*(3): numerator is = (long) indexes[i] * (dataset.length - 1). Since indexes[i] are non negative - dataset has min length of 1, numerator is non negative */ - "upperbound:assignment.type.incompatible",/* (3): Since scale is a positive int, index is in [0, scale], - and (dataset.length - 1) is non-negative int, we can do long-arithmetic on index * (dataset.length - 1) / scale to get a rounded ratio and a remainder - which can be expressed as ints, without risk of overflow */ - "upperbound:array.access.unsafe.high", // (4) if `remainder` is not 0, highest possible value for quotient is `dataset.length - 2` - "unary.increment.type.incompatible" - }) public Map computeInPlace(double @MinLen(1)... dataset) { checkArgument(dataset.length > 0, "Cannot calculate quantiles of an empty dataset"); if (containsNaN(dataset)) { @@ -557,9 +538,6 @@ private static void checkIndex(int index, int scale) { * ({@code required}, {@code to}] are greater than or equal to that value. Therefore, the value at * {@code required} is the value which would appear at that index in the sorted dataset. */ - @SuppressWarnings(value = {"lowerbound:assignment.type.incompatible",/*(1): When entering the loop, - required > from and from >= 0, therefore required >= 1. - At the assignment, partitionPoint >= required, therefore partitionPoint - 1 >= 0. */}) private static void selectInPlace(@IndexFor("#2") int required, double[] array, @IndexFor("#2") int from, @IndexFor("#2") int to) { // If we are looking for the least element in the range, we can just do a linear search for it. // (We will hit this whenever we are doing quantile interpolation: our first selection finds @@ -599,9 +577,6 @@ private static void selectInPlace(@IndexFor("#2") int required, double[] array, * equal to the value at {@code ret} and the values with indexes in ({@code ret}, {@code to}] are * greater than or equal to that. */ - @SuppressWarnings("lowerbound:unary.decrement.type.incompatible")/*(1): Both partitionPoint and i are initialized to the same value `to`. - partitionPoint is decremented at most one more time than i is decremented, therefore partitionPoint >= i-1. - i > from, therefore partitionPoint >= from. Since from is non-negative, therefore partitionPoint is non-negative. */ private static @IndexFor("#1") int partition(double[] array, @IndexFor("#1") int from, @IndexFor("#1") int to) { // Select a pivot, and move it to the start of the slice i.e. to index from. movePivotToStartOfSlice(array, from, to); @@ -654,14 +629,6 @@ private static void movePivotToStartOfSlice(double[] array, @IndexFor("#1") int * allRequired[i]} for {@code i} in the range [{@code requiredFrom}, {@code requiredTo}]. These * indexes must be sorted in the array and must all be in the range [{@code from}, {@code to}]. */ - @SuppressWarnings({"lowerbound:argument.type.incompatible",/*(1): Since allRequired is sorted, and requiredBelow < requiredChosen, - allRequired[requiredBelow] <= allRequired[requiredChosen], therefore allRequired[requiredBelow] is always <= required. Based on the condition - of if and while, allRequired[requiredBelow] != required. Because allRequired[requiredBelow] <= required, we know that allRequired[requiredBelow] < required, - since allRequired[requiredBelow] >= 0, then required > 0. */ - "upperbound:argument.type.incompatible"/*(2): Since allRequired is sorted, and requiredAbove > requiredChosen, - allRequired[requiredAbove] >= allRequired[requiredChosen], therefore allRequired[requiredAbove] is always >= required. Based on the condition - of if and while, allRequired[requiredAbove] != required. Because allRequired[requiredAbove] >= required, we know that allRequired[requiredAbove] > required, - since array.length > allRequired[requiredAbove] > required, required + 1 < array.length. */}) private static void selectAllInPlace( @IndexFor("#4") int[] allRequired, @IndexFor("#1") int requiredFrom, @IndexFor("#1") int requiredTo, double[] array, @IndexFor("#4") int from, @IndexFor("#4") int to) { // Choose the first selection to do... @@ -700,7 +667,7 @@ private static void selectAllInPlace( * minimizes the size of the subranges from which the remaining selections must be done. */ private static @IndexFor("#1") int chooseNextSelection( - int[] allRequired, @IndexFor("#1") int requiredFrom, @IndexFor("#1") int requiredTo, int from, int to) { + int[] allRequired, @IndexFor("#1") int requiredFrom, @IndexFor("#1") int requiredTo, @NonNegative int from, @NonNegative int to) { if (requiredFrom == requiredTo) { return requiredFrom; // only one thing to choose, so choose it } diff --git a/guava/src/com/google/common/primitives/Ints.java b/guava/src/com/google/common/primitives/Ints.java index 4eec9a632934..7da68b484f7a 100644 --- a/guava/src/com/google/common/primitives/Ints.java +++ b/guava/src/com/google/common/primitives/Ints.java @@ -111,7 +111,6 @@ public static int checkedCast(@IntRange(from = Integer.MIN_VALUE, to = Integer.M * {@link Integer#MAX_VALUE} if it is too large, or {@link Integer#MIN_VALUE} if it is too * small */ - @SuppressWarnings("lowerbound:return.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/190 public static @PolyLowerBound int saturatedCast(@PolyLowerBound long value) { if (value > Integer.MAX_VALUE) { return Integer.MAX_VALUE; @@ -186,7 +185,6 @@ public static boolean contains(int[] array, int target) { * @param array the array to search for the sequence {@code target} * @param target the array to search for as a sub-sequence of {@code array} */ - @SuppressWarnings("substringindex:return.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/206 https://github.com/kelloggm/checker-framework/issues/207 https://github.com/kelloggm/checker-framework/issues/208 public static @LTEqLengthOf("#1") @SubstringIndexFor(value = "#1", offset="#2.length - 1") int indexOf(int[] array, int[] target) { checkNotNull(array, "array"); checkNotNull(target, "target"); @@ -302,7 +300,6 @@ public static int constrainToRange(int value, int min, int max) { * pos is increased the same way as length, so pos points to a valid * range of length array.length in result. */ - @SuppressWarnings("upperbound:argument.type.incompatible") // sum of lengths public static int[] concat(int[]... arrays) { int length = 0; for (int[] array : arrays) { @@ -595,8 +592,6 @@ private static class IntArrayAsList extends AbstractList this(array, 0, array.length); } - @SuppressWarnings( - "index") // these three fields need to be initialized in some order, and any ordering leads to the first two issuing errors - since each field is dependent on at least one of the others IntArrayAsList(int @MinLen(1)[] array, @IndexFor("#1") @LessThan("#3") int start, @IndexOrHigh("#1") int end) { this.array = array; this.start = start; @@ -625,14 +620,14 @@ public Spliterator.OfInt spliterator() { } @Override + @SuppressWarnings("signedness:argument") // passing @UnknownSignedness Integer to @Signed int public boolean contains(Object target) { // Overridden to prevent a ton of boxing return (target instanceof Integer) && Ints.indexOf(array, (Integer) target, start, end) != -1; } @Override - @SuppressWarnings( - "lowerbound:return.type.incompatible") // needs https://github.com/kelloggm/checker-framework/issues/227 on static indexOf method + @SuppressWarnings("signedness:argument") // passing @UnknownSignedness Integer to @Signed int public @IndexOrLow("this") int indexOf(Object target) { // Overridden to prevent a ton of boxing if (target instanceof Integer) { @@ -645,8 +640,7 @@ public boolean contains(Object target) { } @Override - @SuppressWarnings( - "lowerbound:return.type.incompatible") // needs https://github.com/kelloggm/checker-framework/issues/227 on static indexOf method + @SuppressWarnings("signedness:argument") // passing @UnknownSignedness Integer to @Signed int public @IndexOrLow("this")int lastIndexOf(Object target) { // Overridden to prevent a ton of boxing if (target instanceof Integer) { @@ -668,7 +662,6 @@ public Integer set(@IndexFor("this") int index, Integer element) { } @Override - @SuppressWarnings("index") // needs https://github.com/kelloggm/checker-framework/issues/229 public List subList(@IndexOrHigh("this") int fromIndex, @IndexOrHigh("this") int toIndex) { int size = size(); checkPositionIndexes(fromIndex, toIndex, size); diff --git a/guava/src/com/google/common/primitives/Longs.java b/guava/src/com/google/common/primitives/Longs.java index a7d0280a8c4a..6cd69b0fc8cc 100644 --- a/guava/src/com/google/common/primitives/Longs.java +++ b/guava/src/com/google/common/primitives/Longs.java @@ -42,6 +42,7 @@ import org.checkerframework.checker.index.qual.SubstringIndexFor; import org.checkerframework.checker.index.qual.HasSubsequence; import org.checkerframework.checker.index.qual.LessThan; +import org.checkerframework.checker.signedness.qual.Signed; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.common.value.qual.IntRange; import org.checkerframework.common.value.qual.MinLen; @@ -87,6 +88,7 @@ private Longs() {} * @param value a primitive {@code long} value * @return a hash code for the value */ + @SuppressWarnings("signedness:shift.unsigned") // value must be positive? public static int hashCode(long value) { return (int) (value ^ (value >>> 32)); } @@ -155,7 +157,6 @@ public static boolean contains(long[] array, long target) { * @param array the array to search for the sequence {@code target} * @param target the array to search for as a sub-sequence of {@code array} */ - @SuppressWarnings("substringindex:return.type.incompatible") // https://github.com/kelloggm/checker-framework/issues/206 https://github.com/kelloggm/checker-framework/issues/207 https://github.com/kelloggm/checker-framework/issues/208 public static @LTEqLengthOf("#1") @SubstringIndexFor(value = "#1", offset="#2.length - 1") int indexOf(long[] array, long[] target) { checkNotNull(array, "array"); checkNotNull(target, "target"); @@ -267,7 +268,6 @@ public static long constrainToRange(long value, long min, long max) { * pos is increased the same way as length, so pos points to a valid * range of length array.length in result. */ - @SuppressWarnings("upperbound:argument.type.incompatible") // sum of lengths public static long[] concat(long[]... arrays) { int length = 0; for (long[] array : arrays) { @@ -351,30 +351,17 @@ private AsciiDigits() {} @IntRange(from = -1, to = 36) byte [] result = new byte[128]; Arrays.fill(result, (byte) -1); for (int i = 0; i < 10; i++) { - @SuppressWarnings({ - "unused", - "lessthan:cast.unsafe", // https://github.com/kelloggm/checker-framework/issues/222 - }) byte _unused3 = result['0' + i] = (byte) i; } for (int i = 0; i < 26; i++) { - @SuppressWarnings({ - "unused", - "upperbound:array.access.unsafe.high.range", // https://github.com/typetools/checker-framework/issues/1669 - "assignment.type.incompatible" // https://github.com/typetools/checker-framework/issues/1669 - }) + @SuppressWarnings("value:assignment") // 10 + i will be <= 36 byte _unused1 = result['A' + i] = (byte) (10 + i); - @SuppressWarnings({ - "unused", - "upperbound:array.access.unsafe.high", // https://github.com/typetools/checker-framework/issues/1669 - "assignment.type.incompatible" // https://github.com/typetools/checker-framework/issues/1669 - }) + @SuppressWarnings("value:assignment") // 10 + i will be <= 36 byte _unused2 = result['a' + i] = (byte) (10 + i); } asciiDigits = result; } - @SuppressWarnings("lowerbound:array.access.unsafe.low") // https://github.com/kelloggm/checker-framework/issues/192 char should be @NonNegative static @IntRange(from = -1, to = 36) int digit(char c) { return (c < 128) ? asciiDigits[c] : -1; } @@ -423,7 +410,6 @@ private AsciiDigits() {} * @since 19.0 */ @Beta - @SuppressWarnings("upperbound") // annotation inferred by contract doesn't propagate through checkNotNull public static @Nullable Long tryParse(String string, @IntRange(from=2, to=36) int radix) { if (checkNotNull(string).isEmpty()) { return null; @@ -733,14 +719,14 @@ public Spliterator.OfLong spliterator() { } @Override + @SuppressWarnings("signedness:argument") // target is signed Long public boolean contains(Object target) { // Overridden to prevent a ton of boxing return (target instanceof Long) && Longs.indexOf(array, (Long) target, start, end) != -1; } @Override - @SuppressWarnings( - "lowerbound:return.type.incompatible") // needs https://github.com/kelloggm/checker-framework/issues/227 on static indexOf method + @SuppressWarnings("signedness:argument") // target is signed Long public @IndexOrLow("this") int indexOf(Object target) { // Overridden to prevent a ton of boxing if (target instanceof Long) { @@ -753,8 +739,7 @@ public boolean contains(Object target) { } @Override - @SuppressWarnings( - "lowerbound:return.type.incompatible") // needs https://github.com/kelloggm/checker-framework/issues/227 on static indexOf method + @SuppressWarnings("signedness:argument") // target is signed Long public @IndexOrLow("this") int lastIndexOf(Object target) { // Overridden to prevent a ton of boxing if (target instanceof Long) { diff --git a/guava/src/com/google/common/primitives/UnsignedInteger.java b/guava/src/com/google/common/primitives/UnsignedInteger.java index 1c7011c6c1d2..4cd3068c0b95 100644 --- a/guava/src/com/google/common/primitives/UnsignedInteger.java +++ b/guava/src/com/google/common/primitives/UnsignedInteger.java @@ -180,14 +180,16 @@ public UnsignedInteger mod(UnsignedInteger val) { * will be equal to {@code this - 2^32}. */ @Override + @SuppressWarnings("cast.unsafe") public @PolyValue int intValue(@PolyValue UnsignedInteger this) { - return value; + return (@PolyValue int) value; } /** Returns the value of this {@code UnsignedInteger} as a {@code long}. */ @Override + @SuppressWarnings("cast.unsafe") public @NonNegative @PolyValue long longValue(@PolyValue UnsignedInteger this) { - return toLong(value); + return (@PolyValue long) toLong(value); } /** @@ -195,6 +197,7 @@ public UnsignedInteger mod(UnsignedInteger val) { * primitive conversion from {@code int} to {@code float}, and correctly rounded. */ @Override + @SuppressWarnings("cast.unsafe") public @PolyValue float floatValue(@PolyValue UnsignedInteger this) { return longValue(); } diff --git a/guava/src/com/google/common/primitives/UnsignedLong.java b/guava/src/com/google/common/primitives/UnsignedLong.java index e3efd8406dc0..07d8280fb3cd 100644 --- a/guava/src/com/google/common/primitives/UnsignedLong.java +++ b/guava/src/com/google/common/primitives/UnsignedLong.java @@ -23,7 +23,10 @@ import java.math.BigInteger; import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.signedness.qual.Signed; +import org.checkerframework.checker.signedness.qual.Unsigned; import org.checkerframework.common.value.qual.IntRange; +import org.checkerframework.common.value.qual.PolyValue; /** * A wrapper class for unsigned {@code long} values, supporting arithmetic operations. @@ -48,9 +51,9 @@ public final class UnsignedLong extends Number implements Comparable= 2^64} */ @CanIgnoreReturnValue + @SuppressWarnings("signedness:cast.unsafe") public static UnsignedLong valueOf(BigInteger value) { checkNotNull(value); checkArgument( value.signum() >= 0 && value.bitLength() <= Long.SIZE, "value (%s) is outside the range for an unsigned long value", value); - return fromLongBits(value.longValue()); + return fromLongBits((@Unsigned long)value.longValue()); } /** @@ -175,7 +179,8 @@ public UnsignedLong mod(UnsignedLong val) { /** Returns the value of this {@code UnsignedLong} as an {@code int}. */ @Override - public int intValue() { + @SuppressWarnings("return") + public @PolyValue int intValue(@PolyValue UnsignedLong this) { return (int) value; } @@ -187,7 +192,8 @@ public int intValue() { * will be equal to {@code this - 2^64}. */ @Override - public long longValue() { + @SuppressWarnings("return") + public @PolyValue long longValue(@PolyValue UnsignedLong this) { return value; } @@ -196,8 +202,11 @@ public long longValue() { * primitive conversion from {@code long} to {@code float}, and correctly rounded. */ @Override - public float floatValue() { - @SuppressWarnings("cast") + @SuppressWarnings({ + "signedness:comparison", // unsigned compare + "value:return" // forDigit + }) + public @PolyValue float floatValue(@PolyValue UnsignedLong this) { float fValue = (float) (value & UNSIGNED_MASK); if (value < 0) { fValue += 0x1.0p63f; @@ -210,8 +219,11 @@ public float floatValue() { * primitive conversion from {@code long} to {@code double}, and correctly rounded. */ @Override - public double doubleValue() { - @SuppressWarnings("cast") + @SuppressWarnings({ + "signedness:comparison", // unsigned compare + "value:return" // forDigit + }) + public @PolyValue double doubleValue(@PolyValue UnsignedLong this) { double dValue = (double) (value & UNSIGNED_MASK); if (value < 0) { dValue += 0x1.0p63; @@ -220,6 +232,7 @@ public double doubleValue() { } /** Returns the value of this {@code UnsignedLong} as a {@link BigInteger}. */ + @SuppressWarnings("signedness:comparison.unsignedlhs") public BigInteger bigIntegerValue() { BigInteger bigInt = BigInteger.valueOf(value & UNSIGNED_MASK); if (value < 0) { @@ -235,6 +248,7 @@ public int compareTo(UnsignedLong o) { } @Override + @SuppressWarnings("signedness:argument") public int hashCode() { return Longs.hashCode(value); } diff --git a/guava/src/com/google/common/primitives/UnsignedLongs.java b/guava/src/com/google/common/primitives/UnsignedLongs.java index 73f7260f71ee..18c2da4fb41d 100644 --- a/guava/src/com/google/common/primitives/UnsignedLongs.java +++ b/guava/src/com/google/common/primitives/UnsignedLongs.java @@ -65,6 +65,7 @@ private UnsignedLongs() {} * longs, that is, {@code a <= b} as unsigned longs if and only if {@code flip(a) <= flip(b)} as * signed longs. */ + @SuppressWarnings("signedness:return") private static @PolySigned long flip(@PolySigned long a) { return a ^ Long.MIN_VALUE; } @@ -80,6 +81,7 @@ private UnsignedLongs() {} * @return a negative value if {@code a} is less than {@code b}; a positive value if {@code a} is * greater than {@code b}; or zero if they are equal */ + @SuppressWarnings("signedness:argument") public static int compare(@Unsigned long a, @Unsigned long b) { return Longs.compare(flip(a), flip(b)); } @@ -92,6 +94,7 @@ public static int compare(@Unsigned long a, @Unsigned long b) { * the array according to {@link #compare} * @throws IllegalArgumentException if {@code array} is empty */ + @SuppressWarnings("signedness:comparison") public static @Unsigned long min(@Unsigned long @MinLen(1)... array) { checkArgument(array.length > 0); long min = flip(array[0]); @@ -112,6 +115,7 @@ public static int compare(@Unsigned long a, @Unsigned long b) { * in the array according to {@link #compare} * @throws IllegalArgumentException if {@code array} is empty */ + @SuppressWarnings("signedness:comparison") public static @Unsigned long max(@Unsigned long @MinLen(1)... array) { checkArgument(array.length > 0); long max = flip(array[0]); @@ -198,6 +202,7 @@ public static void sort(@Unsigned long[] array) { * * @since 23.1 */ + @SuppressWarnings("signedness:argument") public static void sort(@Unsigned long[] array, @IndexOrHigh("#1") int fromIndex, @IndexOrHigh("#1") int toIndex) { checkNotNull(array); checkPositionIndexes(fromIndex, toIndex, array.length); @@ -227,6 +232,7 @@ public static void sortDescending(@Unsigned long[] array) { * * @since 23.1 */ + @SuppressWarnings("signedness:argument") public static void sortDescending(@Unsigned long[] array, @IndexOrHigh("#1") int fromIndex, @IndexOrHigh("#1") int toIndex) { checkNotNull(array); checkPositionIndexes(fromIndex, toIndex, array.length); @@ -249,6 +255,7 @@ public static void sortDescending(@Unsigned long[] array, @IndexOrHigh("#1") int * @param divisor the divisor (denominator) * @throws ArithmeticException if divisor is 0 */ + @SuppressWarnings("signedness:comparison") public static @Unsigned long divide(@Unsigned long dividend, @Unsigned long divisor) { if (divisor < 0) { // i.e., divisor >= 2^63: if (compare(dividend, divisor) < 0) { @@ -269,6 +276,7 @@ public static void sortDescending(@Unsigned long[] array, @IndexOrHigh("#1") int * floor(floor(x)/i) == floor(x/i) for any real x and integer i != 0. The proof is not quite * trivial. */ + @SuppressWarnings("signedness:operation") long quotient = ((dividend >>> 1) / divisor) << 1; long rem = dividend - quotient * divisor; return quotient + (compare(rem, divisor) >= 0 ? 1 : 0); @@ -285,6 +293,7 @@ public static void sortDescending(@Unsigned long[] array, @IndexOrHigh("#1") int * @throws ArithmeticException if divisor is 0 * @since 11.0 */ + @SuppressWarnings("signedness:comparison") public static @Unsigned long remainder(@Unsigned long dividend, @Unsigned long divisor) { if (divisor < 0) { // i.e., divisor >= 2^63: if (compare(dividend, divisor) < 0) { @@ -305,6 +314,7 @@ public static void sortDescending(@Unsigned long[] array, @IndexOrHigh("#1") int * that floor(floor(x)/i) == floor(x/i) for any real x and integer i != 0. The proof is not * quite trivial. */ + @SuppressWarnings("signedness:operation") long quotient = ((dividend >>> 1) / divisor) << 1; long rem = dividend - quotient * divisor; return rem - (compare(rem, divisor) >= 0 ? divisor : 0); @@ -464,9 +474,9 @@ public static String toString(@Unsigned long x) { * Assuming that Character.MIN_RADIX == 2 */ @SuppressWarnings({ - "lowerbound:argument.type.incompatible", // https://github.com/kelloggm/checker-framework/issues/193 - "lowerbound:unary.decrement.type.incompatible", - "lowerbound:array.access.unsafe.low", "lowerbound:compound.assignment.type.incompatible" // ulong converted to string is at most 64 chars + "signedness:comparison", // unsigned compare + "signedness:operation", // unsigned divide + "signedness:argument" // forDigit }) public static String toString(@Unsigned long x, @IntRange(from = Character.MIN_RADIX,to = Character.MAX_RADIX) int radix) { checkArgument( diff --git a/guava/src/com/google/common/util/concurrent/AtomicDouble.java b/guava/src/com/google/common/util/concurrent/AtomicDouble.java index 8f881dddff78..e57bdc7b95f4 100644 --- a/guava/src/com/google/common/util/concurrent/AtomicDouble.java +++ b/guava/src/com/google/common/util/concurrent/AtomicDouble.java @@ -22,6 +22,8 @@ import com.google.j2objc.annotations.ReflectionSupport; import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import org.checkerframework.common.value.qual.PolyValue; + /** * A {@code double} value that may be updated atomically. See the {@link * java.util.concurrent.atomic} package specification for description of the properties of atomic @@ -199,8 +201,9 @@ public String toString() { * conversion. */ @Override - public int intValue() { - return (int) get(); + @SuppressWarnings("cast.unsafe") + public @PolyValue int intValue(@PolyValue AtomicDouble this) { + return (@PolyValue int) get(); } /** @@ -208,8 +211,9 @@ public int intValue() { * conversion. */ @Override - public long longValue() { - return (long) get(); + @SuppressWarnings("cast.unsafe") + public @PolyValue long longValue(@PolyValue AtomicDouble this) { + return (@PolyValue long) get(); } /** @@ -217,14 +221,16 @@ public long longValue() { * conversion. */ @Override - public float floatValue() { - return (float) get(); + @SuppressWarnings("cast.unsafe") + public @PolyValue float floatValue(@PolyValue AtomicDouble this) { + return (@PolyValue float) get(); } /** Returns the value of this {@code AtomicDouble} as a {@code double}. */ @Override - public double doubleValue() { - return get(); + @SuppressWarnings("cast.unsafe") + public @PolyValue double doubleValue(@PolyValue AtomicDouble this) { + return (@PolyValue double) get(); } /** diff --git a/guava/src/com/google/common/util/concurrent/ClosingFuture.java b/guava/src/com/google/common/util/concurrent/ClosingFuture.java index 09767dc00fd4..f2a315875395 100644 --- a/guava/src/com/google/common/util/concurrent/ClosingFuture.java +++ b/guava/src/com/google/common/util/concurrent/ClosingFuture.java @@ -341,8 +341,7 @@ public static final class ValueAndCloser { * @throws CancellationException if the computation was cancelled * @throws ExecutionException if the computation threw an exception */ - @Nullable - public V get() throws ExecutionException { + public @Nullable V get() throws ExecutionException { return getDone(closingFuture.future); } diff --git a/pom.xml b/pom.xml index eb05a1aa331f..13c549ef092d 100644 --- a/pom.xml +++ b/pom.xml @@ -274,7 +274,7 @@ org.checkerframework checker-qual - 3.19.0 + 3.30.0 com.google.errorprone From 833a94056826ef06a3064ee02d09703316551757 Mon Sep 17 00:00:00 2001 From: Mark Roberts Date: Wed, 15 Feb 2023 16:09:38 -0800 Subject: [PATCH 05/21] turn on signedness checking --- azure-pipelines.yml | 2 ++ guava/src/com/google/common/math/LongMath.java | 7 +++++++ guava/src/com/google/common/primitives/UnsignedLongs.java | 5 ++++- typecheck.sh | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 68c2e35c9e04..86223ead9a35 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -30,6 +30,8 @@ jobs: typechecker: regex signatureJob: typechecker: signature + signednessJob: + typechecker: signedness maxParallel: 10 steps: - checkout: self diff --git a/guava/src/com/google/common/math/LongMath.java b/guava/src/com/google/common/math/LongMath.java index d80056ce6af0..367d80f70111 100644 --- a/guava/src/com/google/common/math/LongMath.java +++ b/guava/src/com/google/common/math/LongMath.java @@ -1054,6 +1054,7 @@ public static boolean isPrime(long n) { return true; } + //@SuppressWarnings("signedness:comparison") // n is guaranteed to be positive for (@Unsigned long[] baseSet : millerRabinBaseSets) { if (n <= baseSet[0]) { for (int i = 1; i < baseSet.length; i++) { @@ -1103,6 +1104,7 @@ private enum MillerRabinTester { /** Works for inputs ≤ FLOOR_SQRT_MAX_LONG. */ SMALL { @Override + @SuppressWarnings("signedness:operation") @Unsigned long mulMod(@Unsigned long a, @Unsigned long b, @Unsigned long m) { /* * lowasser, 2015-Feb-12: Benchmarks suggest that changing this to UnsignedLongs.remainder @@ -1114,6 +1116,7 @@ private enum MillerRabinTester { } @Override + @SuppressWarnings("signedness:operation") @Unsigned long squareMod(@Unsigned long a, @Unsigned long m) { return (a * a) % m; } @@ -1121,6 +1124,7 @@ private enum MillerRabinTester { /** Works for all nonnegative signed longs. */ LARGE { /** Returns (a + b) mod m. Precondition: {@code 0 <= a}, {@code b < m < 2^63}. */ + @SuppressWarnings("signedness:comparison") private @Unsigned long plusMod(@Unsigned long a, @Unsigned long b, @Unsigned long m) { return (a >= m - b) ? (a + b - m) : (a + b); } @@ -1139,6 +1143,7 @@ private enum MillerRabinTester { } @Override + @SuppressWarnings("signedness:comparison") @Unsigned long mulMod(@Unsigned long a, @Unsigned long b, @Unsigned long m) { long aHi = a >>> 32; // < 2^31 long bHi = b >>> 32; // < 2^31 @@ -1165,6 +1170,7 @@ private enum MillerRabinTester { } @Override + @SuppressWarnings("signedness:comparison") @Unsigned long squareMod(@Unsigned long a, @Unsigned long m) { long aHi = a >>> 32; // < 2^31 long aLo = a & 0xFFFFFFFFL; // < 2^32 @@ -1188,6 +1194,7 @@ private enum MillerRabinTester { } }; + @SuppressWarnings("signedness:comparison") static boolean test(@Unsigned long base, @Unsigned long n) { // Since base will be considered % n, it's okay if base > FLOOR_SQRT_MAX_LONG, // so long as n <= FLOOR_SQRT_MAX_LONG. diff --git a/guava/src/com/google/common/primitives/UnsignedLongs.java b/guava/src/com/google/common/primitives/UnsignedLongs.java index 18c2da4fb41d..1542a4b8eade 100644 --- a/guava/src/com/google/common/primitives/UnsignedLongs.java +++ b/guava/src/com/google/common/primitives/UnsignedLongs.java @@ -27,8 +27,10 @@ import org.checkerframework.checker.index.qual.IndexOrHigh; import org.checkerframework.common.value.qual.IntRange; import org.checkerframework.common.value.qual.MinLen; -import org.checkerframework.checker.signedness.qual.Unsigned; +import org.checkerframework.checker.signedness.qual.Signed; import org.checkerframework.checker.signedness.qual.PolySigned; +import org.checkerframework.checker.signedness.qual.Unsigned; +import org.checkerframework.framework.qual.AnnotatedFor; /** * Static utility methods pertaining to {@code long} primitives that interpret values as @@ -53,6 +55,7 @@ * @author Colin Evans * @since 10.0 */ +@AnnotatedFor({"signedness"}) @Beta @GwtCompatible public final class UnsignedLongs { diff --git a/typecheck.sh b/typecheck.sh index a30b7ecb91b9..c41441aecd5b 100755 --- a/typecheck.sh +++ b/typecheck.sh @@ -40,6 +40,8 @@ elif [[ "$1" == "regex" ]]; then (cd guava && mvn -B compile -P checkerframework-local -Dcheckerframework.checkers=org.checkerframework.checker.regex.RegexChecker) elif [[ "$1" == "signature" ]]; then (cd guava && mvn -B compile -P checkerframework-local -Dcheckerframework.checkers=org.checkerframework.checker.signature.SignatureChecker) +elif [[ "$1" == "signedness" ]]; then + (cd guava && mvn -B compile -P checkerframework-local -Dcheckerframework.checkers=org.checkerframework.checker.signedness.SignednessChecker) elif [[ "$1" == "nothing" ]]; then true else From 410394a72489163046f2f90318eb9b84a439cc70 Mon Sep 17 00:00:00 2001 From: Mark Roberts Date: Wed, 12 Apr 2023 10:23:57 -0700 Subject: [PATCH 06/21] Merge v31.1 source from google/guava --- .github/dependabot.yml | 16 + .github/workflows/ci.yml | 30 +- README-typetools.md | 23 +- README.md | 39 +- android/guava-bom/pom.xml | 2 +- android/guava-testlib/pom.xml | 6 +- .../testing/AbstractContainerTester.java | 4 +- .../collect/testing/AbstractMapTester.java | 8 +- .../testing/CollectionTestSuiteBuilder.java | 2 + .../testing/DerivedCollectionGenerators.java | 13 +- .../FeatureSpecificTestSuiteBuilder.java | 20 +- .../common/collect/testing/Helpers.java | 18 +- .../collect/testing/ListTestSuiteBuilder.java | 2 + .../collect/testing/MapInterfaceTest.java | 212 +-- .../collect/testing/MapTestSuiteBuilder.java | 8 + .../collect/testing/MinimalCollection.java | 4 +- .../collect/testing/MinimalIterable.java | 4 +- .../common/collect/testing/MinimalSet.java | 4 +- .../testing/NavigableMapTestSuiteBuilder.java | 4 +- .../testing/NavigableSetTestSuiteBuilder.java | 9 +- .../collect/testing/OneSizeGenerator.java | 2 +- .../ReserializingTestCollectionGenerator.java | 2 +- .../ReserializingTestSetGenerator.java | 2 +- .../common/collect/testing/SafeTreeSet.java | 8 +- .../collect/testing/SetTestSuiteBuilder.java | 2 + .../testing/SortedMapInterfaceTest.java | 6 +- .../testing/SortedMapTestSuiteBuilder.java | 10 +- .../testing/SortedSetTestSuiteBuilder.java | 13 +- .../collect/testing/features/FeatureUtil.java | 8 +- .../google/AbstractMultimapTester.java | 10 +- .../testing/google/BiMapTestSuiteBuilder.java | 6 + .../DerivedGoogleCollectionGenerators.java | 6 +- .../collect/testing/google/MapGenerators.java | 12 +- .../google/MultimapTestSuiteBuilder.java | 12 + .../google/MultisetNavigationTester.java | 2 +- .../google/MultisetTestSuiteBuilder.java | 6 + .../google/SetMultimapAsMapTester.java | 2 +- .../SortedMultisetTestSuiteBuilder.java | 18 +- .../google/SortedSetMultimapAsMapTester.java | 2 +- .../google/UnmodifiableCollectionTests.java | 4 +- .../testers/CollectionIteratorTester.java | 6 +- .../testers/CollectionToArrayTester.java | 4 +- .../testers/NavigableSetNavigationTester.java | 2 +- .../common/escape/testing/EscaperAsserts.java | 2 - .../testing/AbstractPackageSanityTests.java | 20 +- .../common/testing/ArbitraryInstances.java | 12 +- .../common/testing/ClassSanityTester.java | 10 +- .../google/common/testing/EqualsTester.java | 4 +- .../common/testing/EquivalenceTester.java | 7 +- .../com/google/common/testing/FakeTicker.java | 2 - .../testing/ForwardingWrapperTester.java | 6 +- .../common/testing/FreshValueGenerator.java | 243 ++-- .../google/common/testing/GcFinalization.java | 35 +- .../common/testing/NullPointerTester.java | 17 +- .../common/testing/RelationshipTester.java | 2 +- .../common/testing/SerializableTester.java | 3 - .../google/common/testing/TestLogHandler.java | 6 +- .../testing/AbstractListenableFutureTest.java | 109 +- .../testing/MockFutureListener.java | 8 +- .../SameThreadScheduledExecutorService.java | 4 +- .../concurrent/testing/TestingExecutors.java | 6 +- .../FeatureSpecificTestSuiteBuilderTest.java | 6 +- .../testing/MapTestSuiteBuilderTests.java | 92 ++ .../common/testing/ClassSanityTesterTest.java | 36 +- .../common/testing/EquivalenceTesterTest.java | 2 +- .../common/testing/NullPointerTesterTest.java | 78 +- .../common/base/StringsRepeatBenchmark.java | 6 +- .../common/base/ToStringHelperBenchmark.java | 2 + .../ConcurrentHashMultisetBenchmark.java | 12 +- .../google/common/collect/MapBenchmark.java | 2 +- .../concurrent/ExecutionListBenchmark.java | 8 +- .../FuturesGetCheckedBenchmark.java | 7 +- .../MonitorBasedArrayBlockingQueue.java | 72 +- .../MonitorBasedPriorityBlockingQueue.java | 68 +- android/guava-tests/pom.xml | 9 +- .../common/base/AbstractIteratorTest.java | 2 +- .../com/google/common/base/AsciiTest.java | 13 +- .../google/common/base/CharMatcherTest.java | 2 +- .../com/google/common/base/OptionalTest.java | 6 + .../google/common/base/PreconditionsTest.java | 19 +- .../common/base/ToStringHelperTest.java | 38 +- .../com/google/common/base/VerifyTest.java | 8 +- .../common/cache/CacheBuilderFactory.java | 4 +- .../com/google/common/cache/CacheTesting.java | 4 +- .../google/common/cache/LocalCacheTest.java | 2 +- .../common/cache/TestingCacheLoaders.java | 4 +- .../common/collect/AbstractIteratorTest.java | 1 + .../common/collect/AbstractMapEntryTest.java | 3 +- .../common/collect/DiscreteDomainTest.java | 44 + .../common/collect/FluentIterableTest.java | 4 +- .../common/collect/ForwardingMapTest.java | 2 +- .../collect/ForwardingSortedMultisetTest.java | 10 +- .../common/collect/ImmutableBiMapTest.java | 173 ++- .../collect/ImmutableListMultimapTest.java | 10 + .../common/collect/ImmutableMapTest.java | 412 +++++- .../common/collect/ImmutableMultimapTest.java | 11 + .../common/collect/ImmutableRangeSetTest.java | 4 + .../collect/ImmutableSetMultimapTest.java | 10 + .../collect/ImmutableSortedMapTest.java | 140 +- .../collect/ImmutableSortedSetTest.java | 2 +- .../google/common/collect/IteratorsTest.java | 4 + .../collect/LinkedListMultimapTest.java | 10 + .../com/google/common/collect/ListsTest.java | 16 +- .../google/common/collect/MapMakerTest.java | 41 +- .../common/collect/MapsCollectionTest.java | 6 +- .../com/google/common/collect/MapsTest.java | 10 +- .../collect/MapsTransformValuesTest.java | 6 +- ...ansformValuesUnmodifiableIteratorTest.java | 6 +- .../google/common/collect/MultimapsTest.java | 13 +- .../google/common/collect/OrderingTest.java | 4 +- .../com/google/common/collect/RangeTest.java | 10 + .../collect/RegularImmutableAsListTest.java | 3 +- .../common/collect/SetOperationsTest.java | 166 ++- .../com/google/common/collect/SetsTest.java | 5 +- .../collect/SimpleAbstractMultisetTest.java | 6 +- .../common/collect/SynchronizedDequeTest.java | 5 +- .../common/collect/SynchronizedMapTest.java | 10 +- .../collect/SynchronizedMultimapTest.java | 20 +- .../common/collect/SynchronizedQueueTest.java | 5 +- .../common/collect/SynchronizedSetTest.java | 10 +- .../common/collect/SynchronizedTableTest.java | 6 +- .../common/collect/TopKSelectorTest.java | 11 + .../collect/UnmodifiableIteratorTest.java | 1 + .../collect/UnmodifiableListIteratorTest.java | 3 + .../google/common/escape/EscapersTest.java | 2 +- .../common/eventbus/PackageSanityTests.java | 4 +- .../google/common/eventbus/StringCatcher.java | 6 +- .../outside/AbstractEventBusTest.java | 55 + .../AbstractNotAnnotatedInSuperclassTest.java | 61 + .../AnnotatedAndAbstractInSuperclassTest.java | 63 + .../AnnotatedNotAbstractInSuperclassTest.java | 116 ++ .../AnnotatedSubscriberFinderTests.java | 448 ------- .../outside/BaseSubscriberFinderTest.java | 53 + .../eventbus/outside/DeepInterfaceTest.java | 153 +++ ...rAbstractNorAnnotatedInSuperclassTest.java | 74 ++ .../com/google/common/graph/MapCacheTest.java | 21 - .../google/common/hash/BloomFilterTest.java | 9 +- .../common/hash/Fingerprint2011Test.java | 233 ++++ .../google/common/hash/HashFunctionEnum.java | 1 + .../com/google/common/hash/HashTestUtils.java | 4 +- .../com/google/common/hash/HashingTest.java | 19 +- .../google/common/hash/Murmur3Hash32Test.java | 79 +- .../google/common/io/BaseEncodingTest.java | 14 +- .../com/google/common/io/ByteSourceTest.java | 3 +- .../google/common/io/ByteSourceTester.java | 2 +- .../com/google/common/io/ByteStreamsTest.java | 41 +- .../common/io/CharSequenceReaderTest.java | 6 +- .../com/google/common/io/CharSourceTest.java | 3 +- .../test/com/google/common/io/CloserTest.java | 10 +- .../io/LittleEndianDataInputStreamTest.java | 1 + .../common/io/PatternFilenameFilterTest.java | 13 + .../google/common/io/SourceSinkFactories.java | 10 +- .../google/common/io/SourceSinkTester.java | 2 +- .../com/google/common/math/IntMathTest.java | 7 +- .../common/math/MathPreconditionsTest.java | 11 + .../common/math/QuantilesAlgorithm.java | 4 +- .../com/google/common/math/QuantilesTest.java | 10 +- .../google/common/net/HostAndPortTest.java | 7 + .../google/common/net/HostSpecifierTest.java | 5 +- .../google/common/net/HttpHeadersTest.java | 4 +- .../google/common/net/InetAddressesTest.java | 28 + .../common/net/InternetDomainNameTest.java | 4 +- .../com/google/common/net/MediaTypeTest.java | 3 +- .../google/common/net/PercentEscaperTest.java | 13 +- .../common/primitives/BooleansTest.java | 3 +- .../common/primitives/UnsignedLongTest.java | 25 +- .../google/common/reflect/ElementTest.java | 247 ---- .../google/common/reflect/InvokableTest.java | 199 ++- .../google/common/reflect/TypeTokenTest.java | 16 +- .../AbstractAbstractFutureTest.java | 1 - ...st.java => AbstractClosingFutureTest.java} | 193 +-- .../AbstractExecutionThreadServiceTest.java | 9 - .../concurrent/AbstractFutureBenchmarks.java | 10 +- .../AbstractFutureCancellationCauseTest.java | 1 + .../util/concurrent/AbstractFutureTest.java | 2 +- .../concurrent/AbstractIdleServiceTest.java | 1 - .../AbstractScheduledServiceTest.java | 90 +- .../util/concurrent/AbstractServiceTest.java | 9 - .../concurrent/AtomicDoubleArrayTest.java | 2 - .../util/concurrent/AtomicDoubleTest.java | 2 - .../concurrent/AtomicLongMapBasherTest.java | 34 +- .../util/concurrent/AtomicLongMapTest.java | 6 +- .../ClosingFutureFinishToFutureTest.java | 94 ++ ...osingFutureFinishToValueAndCloserTest.java | 148 +++ .../CycleDetectingLockFactoryTest.java | 3 - .../util/concurrent/ExecutionListTest.java | 3 - .../concurrent/ExecutionSequencerTest.java | 3 - .../util/concurrent/FluentFutureTest.java | 1 - .../concurrent/ForwardingObjectTester.java | 2 +- .../util/concurrent/FutureCallbackTest.java | 6 +- .../concurrent/FuturesGetCheckedTest.java | 5 +- .../common/util/concurrent/FuturesTest.java | 35 +- .../concurrent/FuturesTransformAsyncTest.java | 1 - .../util/concurrent/GeneratedMonitorTest.java | 1 - .../concurrent/InterruptibleMonitorTest.java | 1 - .../concurrent/InterruptibleTaskTest.java | 54 +- .../util/concurrent/JSR166TestCase.java | 2 +- .../concurrent/JdkFutureAdaptersTest.java | 3 - .../concurrent/ListenableFutureTaskTest.java | 3 - .../concurrent/ListenableFutureTester.java | 6 +- .../concurrent/ListenerCallQueueTest.java | 2 - .../util/concurrent/MonitorTestCase.java | 1 - .../util/concurrent/MoreExecutorsTest.java | 32 +- .../concurrent/SequentialExecutorTest.java | 10 +- .../util/concurrent/ServiceManagerTest.java | 22 +- .../util/concurrent/SettableFutureTest.java | 4 - .../concurrent/SimpleTimeLimiterTest.java | 1 - .../common/util/concurrent/StripedTest.java | 6 +- .../concurrent/SupplementalMonitorTest.java | 1 - .../common/util/concurrent/TestThread.java | 6 +- .../concurrent/ThreadFactoryBuilderTest.java | 10 - .../TrustedListenableFutureTaskTest.java | 3 - .../UncaughtExceptionHandlersTest.java | 1 - .../concurrent/UninterruptibleFutureTest.java | 11 - .../UninterruptibleMonitorTest.java | 1 - .../util/concurrent/UninterruptiblesTest.java | 1 - android/guava/pom.xml | 43 +- .../src/com/google/common/base/Absent.java | 7 +- .../google/common/base/AbstractIterator.java | 16 +- .../src/com/google/common/base/Ascii.java | 5 +- .../com/google/common/base/CaseFormat.java | 10 +- .../com/google/common/base/CharMatcher.java | 5 +- .../src/com/google/common/base/Charsets.java | 1 + .../com/google/common/base/CommonMatcher.java | 1 + .../com/google/common/base/CommonPattern.java | 1 + .../src/com/google/common/base/Converter.java | 160 ++- .../src/com/google/common/base/Defaults.java | 46 +- .../base/ElementTypesAreNonnullByDefault.java | 41 + .../src/com/google/common/base/Enums.java | 9 +- .../com/google/common/base/Equivalence.java | 83 +- .../base/ExtraObjectsMethodsForWeb.java | 1 + .../base/FinalizablePhantomReference.java | 4 +- .../common/base/FinalizableReference.java | 1 + .../base/FinalizableReferenceQueue.java | 13 +- .../common/base/FinalizableSoftReference.java | 4 +- .../common/base/FinalizableWeakReference.java | 4 +- .../src/com/google/common/base/Function.java | 12 +- .../common/base/FunctionalEquivalence.java | 11 +- .../src/com/google/common/base/Functions.java | 105 +- .../common/base/Java8Compatibility.java | 44 + .../com/google/common/base/Java8Usage.java | 45 - .../com/google/common/base/JdkPattern.java | 1 + .../src/com/google/common/base/Joiner.java | 82 +- .../com/google/common/base/MoreObjects.java | 115 +- .../com/google/common/base/NullnessCasts.java | 60 + .../src/com/google/common/base/Objects.java | 8 +- .../src/com/google/common/base/Optional.java | 10 +- .../common/base/PairwiseEquivalence.java | 16 +- .../common/base/ParametricNullness.java | 52 + .../google/common/base/PatternCompiler.java | 1 + .../src/com/google/common/base/Platform.java | 10 +- .../com/google/common/base/Preconditions.java | 374 +++--- .../src/com/google/common/base/Predicate.java | 10 +- .../com/google/common/base/Predicates.java | 139 +- .../src/com/google/common/base/Present.java | 7 +- .../google/common/base/SmallCharMatcher.java | 1 + .../src/com/google/common/base/Splitter.java | 3 + .../common/base/StandardSystemProperty.java | 5 +- .../src/com/google/common/base/Stopwatch.java | 5 +- .../src/com/google/common/base/Strings.java | 17 +- .../src/com/google/common/base/Supplier.java | 5 +- .../src/com/google/common/base/Suppliers.java | 89 +- .../com/google/common/base/Throwables.java | 60 +- .../src/com/google/common/base/Ticker.java | 1 + .../src/com/google/common/base/Utf8.java | 1 + .../src/com/google/common/base/Verify.java | 120 +- .../google/common/base/VerifyException.java | 9 +- .../common/base/internal/Finalizer.java | 16 +- .../google/common/cache/AbstractCache.java | 10 +- .../common/cache/AbstractLoadingCache.java | 1 + .../src/com/google/common/cache/Cache.java | 16 +- .../com/google/common/cache/CacheBuilder.java | 78 +- .../google/common/cache/CacheBuilderSpec.java | 64 +- .../com/google/common/cache/CacheLoader.java | 1 + .../com/google/common/cache/CacheStats.java | 5 +- .../ElementTypesAreNonnullByDefault.java | 41 + .../google/common/cache/ForwardingCache.java | 14 +- .../common/cache/ForwardingLoadingCache.java | 1 + .../com/google/common/cache/LoadingCache.java | 3 + .../com/google/common/cache/LocalCache.java | 162 +-- .../com/google/common/cache/LongAddable.java | 1 + .../com/google/common/cache/LongAddables.java | 4 +- .../com/google/common/cache/LongAdder.java | 1 + .../common/cache/ParametricNullness.java | 52 + .../google/common/cache/ReferenceEntry.java | 8 +- .../com/google/common/cache/RemovalCause.java | 1 + .../google/common/cache/RemovalListener.java | 1 + .../google/common/cache/RemovalListeners.java | 17 +- .../common/cache/RemovalNotification.java | 13 +- .../com/google/common/cache/Striped64.java | 10 +- .../src/com/google/common/cache/Weigher.java | 1 + .../google/common/collect/AbstractBiMap.java | 102 +- .../collect/AbstractIndexedListIterator.java | 8 +- .../common/collect/AbstractIterator.java | 19 +- .../common/collect/AbstractListMultimap.java | 23 +- .../collect/AbstractMapBasedMultimap.java | 274 ++-- .../collect/AbstractMapBasedMultiset.java | 30 +- .../common/collect/AbstractMapEntry.java | 14 +- .../common/collect/AbstractMultimap.java | 35 +- .../common/collect/AbstractMultiset.java | 27 +- .../common/collect/AbstractNavigableMap.java | 56 +- .../common/collect/AbstractRangeSet.java | 6 +- .../collect/AbstractSequentialIterator.java | 19 +- .../common/collect/AbstractSetMultimap.java | 23 +- .../AbstractSortedKeySortedSetMultimap.java | 6 +- .../collect/AbstractSortedMultiset.java | 19 +- .../collect/AbstractSortedSetMultimap.java | 19 +- .../google/common/collect/AbstractTable.java | 39 +- .../common/collect/AllEqualOrdering.java | 15 +- .../common/collect/ArrayListMultimap.java | 16 +- .../com/google/common/collect/ArrayTable.java | 168 ++- .../common/collect/BaseImmutableMultimap.java | 1 + .../src/com/google/common/collect/BiMap.java | 22 +- .../com/google/common/collect/BoundType.java | 5 +- .../common/collect/ByFunctionOrdering.java | 11 +- .../google/common/collect/CartesianList.java | 13 +- .../common/collect/ClassToInstanceMap.java | 24 +- .../common/collect/CollectPreconditions.java | 1 + .../google/common/collect/Collections2.java | 56 +- .../google/common/collect/CompactHashMap.java | 378 ++++-- .../google/common/collect/CompactHashSet.java | 180 ++- .../google/common/collect/CompactHashing.java | 24 +- .../common/collect/CompactLinkedHashMap.java | 61 +- .../common/collect/CompactLinkedHashSet.java | 73 +- .../common/collect/ComparatorOrdering.java | 11 +- .../google/common/collect/Comparators.java | 25 +- .../common/collect/ComparisonChain.java | 37 +- .../common/collect/CompoundOrdering.java | 10 +- .../common/collect/ComputationException.java | 5 +- .../collect/ConcurrentHashMultiset.java | 48 +- .../collect/ConsumingQueueIterator.java | 19 +- .../google/common/collect/ContiguousSet.java | 24 +- .../src/com/google/common/collect/Count.java | 5 +- .../src/com/google/common/collect/Cut.java | 39 +- .../common/collect/DenseImmutableTable.java | 33 +- .../DescendingImmutableSortedMultiset.java | 7 +- .../collect/DescendingImmutableSortedSet.java | 11 +- .../common/collect/DescendingMultiset.java | 33 +- .../google/common/collect/DiscreteDomain.java | 19 +- .../ElementTypesAreNonnullByDefault.java | 41 + .../common/collect/EmptyContiguousSet.java | 13 +- .../collect/EmptyImmutableListMultimap.java | 1 + .../collect/EmptyImmutableSetMultimap.java | 1 + .../com/google/common/collect/EnumBiMap.java | 3 +- .../google/common/collect/EnumHashBiMap.java | 25 +- .../google/common/collect/EnumMultiset.java | 20 +- .../google/common/collect/EvictingQueue.java | 27 +- .../common/collect/ExplicitOrdering.java | 5 +- .../common/collect/FilteredEntryMultimap.java | 50 +- .../collect/FilteredEntrySetMultimap.java | 13 +- .../collect/FilteredKeyListMultimap.java | 14 +- .../common/collect/FilteredKeyMultimap.java | 41 +- .../collect/FilteredKeySetMultimap.java | 16 +- .../common/collect/FilteredMultimap.java | 5 +- .../collect/FilteredMultimapValues.java | 11 +- .../common/collect/FilteredSetMultimap.java | 5 +- .../google/common/collect/FluentIterable.java | 76 +- .../collect/ForwardingBlockingDeque.java | 5 + .../common/collect/ForwardingCollection.java | 28 +- .../collect/ForwardingConcurrentMap.java | 6 +- .../common/collect/ForwardingDeque.java | 29 +- .../ForwardingImmutableCollection.java | 1 + .../collect/ForwardingImmutableList.java | 1 + .../collect/ForwardingImmutableMap.java | 1 + .../collect/ForwardingImmutableSet.java | 1 + .../common/collect/ForwardingIterator.java | 6 +- .../google/common/collect/ForwardingList.java | 28 +- .../collect/ForwardingListIterator.java | 11 +- .../collect/ForwardingListMultimap.java | 14 +- .../google/common/collect/ForwardingMap.java | 31 +- .../common/collect/ForwardingMapEntry.java | 16 +- .../common/collect/ForwardingMultimap.java | 27 +- .../common/collect/ForwardingMultiset.java | 33 +- .../collect/ForwardingNavigableMap.java | 91 +- .../collect/ForwardingNavigableSet.java | 58 +- .../common/collect/ForwardingObject.java | 1 + .../common/collect/ForwardingQueue.java | 16 +- .../google/common/collect/ForwardingSet.java | 11 +- .../common/collect/ForwardingSetMultimap.java | 14 +- .../common/collect/ForwardingSortedMap.java | 41 +- .../collect/ForwardingSortedMultiset.java | 29 +- .../common/collect/ForwardingSortedSet.java | 52 +- .../collect/ForwardingSortedSetMultimap.java | 16 +- .../common/collect/ForwardingTable.java | 31 +- .../google/common/collect/GeneralRange.java | 95 +- .../google/common/collect/GwtTransient.java | 1 + .../google/common/collect/HashBasedTable.java | 43 +- .../com/google/common/collect/HashBiMap.java | 210 +-- .../google/common/collect/HashMultimap.java | 17 +- .../google/common/collect/HashMultiset.java | 15 +- .../com/google/common/collect/Hashing.java | 5 +- .../common/collect/ImmutableAsList.java | 4 +- .../google/common/collect/ImmutableBiMap.java | 221 +++- .../collect/ImmutableClassToInstanceMap.java | 16 +- .../common/collect/ImmutableCollection.java | 45 +- .../google/common/collect/ImmutableEntry.java | 19 +- .../common/collect/ImmutableEnumMap.java | 10 +- .../common/collect/ImmutableEnumSet.java | 6 +- .../google/common/collect/ImmutableList.java | 32 +- .../common/collect/ImmutableListMultimap.java | 24 +- .../google/common/collect/ImmutableMap.java | 453 ++++++- .../common/collect/ImmutableMapEntrySet.java | 8 +- .../common/collect/ImmutableMapKeySet.java | 5 +- .../common/collect/ImmutableMapValues.java | 5 +- .../common/collect/ImmutableMultimap.java | 68 +- .../common/collect/ImmutableMultiset.java | 54 +- ...eMultisetGwtSerializationDependencies.java | 1 + .../common/collect/ImmutableRangeMap.java | 15 +- .../common/collect/ImmutableRangeSet.java | 23 +- .../google/common/collect/ImmutableSet.java | 37 +- .../common/collect/ImmutableSetMultimap.java | 44 +- .../common/collect/ImmutableSortedMap.java | 296 ++++- .../ImmutableSortedMapFauxverideShim.java | 157 +++ .../collect/ImmutableSortedMultiset.java | 19 +- ...ImmutableSortedMultisetFauxverideShim.java | 10 + .../common/collect/ImmutableSortedSet.java | 33 +- .../ImmutableSortedSetFauxverideShim.java | 11 + .../google/common/collect/ImmutableTable.java | 45 +- .../common/collect/IndexedImmutableSet.java | 4 +- .../com/google/common/collect/Interner.java | 3 +- .../com/google/common/collect/Interners.java | 20 +- .../com/google/common/collect/Iterables.java | 163 ++- .../com/google/common/collect/Iterators.java | 258 ++-- .../collect/LexicographicalOrdering.java | 9 +- .../common/collect/LinkedHashMultimap.java | 142 +- .../common/collect/LinkedHashMultiset.java | 19 +- .../common/collect/LinkedListMultimap.java | 184 +-- .../google/common/collect/ListMultimap.java | 18 +- .../src/com/google/common/collect/Lists.java | 177 +-- .../google/common/collect/MapDifference.java | 14 +- .../com/google/common/collect/MapMaker.java | 9 +- .../common/collect/MapMakerInternalMap.java | 108 +- .../src/com/google/common/collect/Maps.java | 1021 ++++++++++----- .../common/collect/MinMaxPriorityQueue.java | 55 +- .../com/google/common/collect/Multimap.java | 33 +- .../common/collect/MultimapBuilder.java | 104 +- .../com/google/common/collect/Multimaps.java | 330 +++-- .../com/google/common/collect/Multiset.java | 36 +- .../com/google/common/collect/Multisets.java | 149 ++- .../collect/MutableClassToInstanceMap.java | 27 +- .../common/collect/NaturalOrdering.java | 32 +- .../google/common/collect/NullnessCasts.java | 68 + .../common/collect/NullsFirstOrdering.java | 22 +- .../common/collect/NullsLastOrdering.java | 22 +- .../google/common/collect/ObjectArrays.java | 36 +- .../common/collect/ObjectCountHashMap.java | 47 +- .../collect/ObjectCountLinkedHashMap.java | 18 +- .../com/google/common/collect/Ordering.java | 54 +- .../common/collect/ParametricNullness.java | 52 + .../common/collect/PeekingIterator.java | 8 +- .../com/google/common/collect/Platform.java | 36 +- .../src/com/google/common/collect/Queues.java | 18 +- .../src/com/google/common/collect/Range.java | 26 +- .../com/google/common/collect/RangeMap.java | 15 +- .../com/google/common/collect/RangeSet.java | 8 +- .../common/collect/RegularContiguousSet.java | 29 +- .../collect/RegularImmutableAsList.java | 7 +- .../common/collect/RegularImmutableBiMap.java | 32 +- .../common/collect/RegularImmutableList.java | 14 +- .../common/collect/RegularImmutableMap.java | 248 +++- .../collect/RegularImmutableMultiset.java | 14 +- .../common/collect/RegularImmutableSet.java | 30 +- .../RegularImmutableSortedMultiset.java | 7 +- .../collect/RegularImmutableSortedSet.java | 18 +- .../common/collect/RegularImmutableTable.java | 38 +- .../collect/ReverseNaturalOrdering.java | 25 +- .../common/collect/ReverseOrdering.java | 21 +- .../google/common/collect/RowSortedTable.java | 6 +- .../google/common/collect/Serialization.java | 35 +- .../google/common/collect/SetMultimap.java | 21 +- .../src/com/google/common/collect/Sets.java | 286 +++-- .../common/collect/SingletonImmutableSet.java | 38 +- .../collect/SingletonImmutableTable.java | 1 + .../google/common/collect/SortedIterable.java | 4 +- .../common/collect/SortedIterables.java | 5 +- .../google/common/collect/SortedLists.java | 58 +- .../common/collect/SortedMapDifference.java | 5 +- .../google/common/collect/SortedMultiset.java | 22 +- .../common/collect/SortedMultisetBridge.java | 4 +- .../common/collect/SortedMultisets.java | 55 +- .../common/collect/SortedSetMultimap.java | 21 +- .../common/collect/SparseImmutableTable.java | 20 +- .../collect/StandardRowSortedTable.java | 3 + .../google/common/collect/StandardTable.java | 192 ++- .../google/common/collect/Synchronized.java | 425 +++--- .../src/com/google/common/collect/Table.java | 52 +- .../src/com/google/common/collect/Tables.java | 153 ++- .../google/common/collect/TopKSelector.java | 44 +- .../common/collect/TransformedIterator.java | 9 +- .../collect/TransformedListIterator.java | 11 +- .../google/common/collect/TreeBasedTable.java | 73 +- .../google/common/collect/TreeMultimap.java | 17 +- .../google/common/collect/TreeMultiset.java | 237 ++-- .../google/common/collect/TreeRangeMap.java | 74 +- .../google/common/collect/TreeRangeSet.java | 78 +- .../google/common/collect/TreeTraverser.java | 3 + .../common/collect/UnmodifiableIterator.java | 4 +- .../collect/UnmodifiableListIterator.java | 10 +- .../collect/UnmodifiableSortedMultiset.java | 23 +- .../common/collect/UsingToStringOrdering.java | 1 + .../common/escape/ArrayBasedCharEscaper.java | 8 +- .../common/escape/ArrayBasedEscaperMap.java | 5 +- .../escape/ArrayBasedUnicodeEscaper.java | 14 +- .../com/google/common/escape/CharEscaper.java | 5 +- .../common/escape/CharEscaperBuilder.java | 12 +- .../ElementTypesAreNonnullByDefault.java | 41 + .../src/com/google/common/escape/Escaper.java | 9 +- .../com/google/common/escape/Escapers.java | 22 +- .../common/escape/ParametricNullness.java | 52 + .../com/google/common/escape/Platform.java | 1 + .../google/common/escape/UnicodeEscaper.java | 5 +- .../eventbus/AllowConcurrentEvents.java | 3 +- .../google/common/eventbus/AsyncEventBus.java | 3 +- .../com/google/common/eventbus/DeadEvent.java | 3 +- .../google/common/eventbus/Dispatcher.java | 1 + .../ElementTypesAreNonnullByDefault.java | 41 + .../com/google/common/eventbus/EventBus.java | 59 +- .../common/eventbus/ParametricNullness.java | 52 + .../com/google/common/eventbus/Subscribe.java | 3 +- .../google/common/eventbus/Subscriber.java | 20 +- .../eventbus/SubscriberExceptionContext.java | 5 +- .../eventbus/SubscriberExceptionHandler.java | 2 + .../common/eventbus/SubscriberRegistry.java | 5 +- .../common/graph/AbstractBaseGraph.java | 29 +- .../AbstractDirectedNetworkConnections.java | 22 +- .../google/common/graph/AbstractGraph.java | 5 +- .../common/graph/AbstractGraphBuilder.java | 1 + .../google/common/graph/AbstractNetwork.java | 11 +- .../AbstractUndirectedNetworkConnections.java | 14 +- .../common/graph/AbstractValueGraph.java | 10 +- .../com/google/common/graph/BaseGraph.java | 1 + .../graph/DirectedGraphConnections.java | 91 +- .../DirectedMultiNetworkConnections.java | 13 +- .../graph/DirectedNetworkConnections.java | 6 +- .../google/common/graph/EdgesConnecting.java | 7 +- .../com/google/common/graph/ElementOrder.java | 19 +- .../ElementTypesAreNonnullByDefault.java | 41 + .../com/google/common/graph/EndpointPair.java | 16 +- .../common/graph/EndpointPairIterator.java | 30 +- .../google/common/graph/ForwardingGraph.java | 3 +- .../common/graph/ForwardingNetwork.java | 6 +- .../common/graph/ForwardingValueGraph.java | 13 +- .../src/com/google/common/graph/Graph.java | 5 +- .../com/google/common/graph/GraphBuilder.java | 3 +- .../google/common/graph/GraphConnections.java | 7 +- .../google/common/graph/GraphConstants.java | 2 + .../src/com/google/common/graph/Graphs.java | 34 +- .../google/common/graph/ImmutableGraph.java | 5 +- .../google/common/graph/ImmutableNetwork.java | 34 +- .../common/graph/ImmutableValueGraph.java | 18 +- .../google/common/graph/IncidentEdgeSet.java | 11 +- .../google/common/graph/MapIteratorCache.java | 46 +- .../common/graph/MapRetrievalCache.java | 22 +- .../common/graph/MultiEdgesConnecting.java | 8 +- .../com/google/common/graph/MutableGraph.java | 1 + .../google/common/graph/MutableNetwork.java | 1 + .../common/graph/MutableValueGraph.java | 6 + .../src/com/google/common/graph/Network.java | 9 +- .../google/common/graph/NetworkBuilder.java | 1 + .../common/graph/NetworkConnections.java | 3 + .../common/graph/ParametricNullness.java | 52 + .../common/graph/PredecessorsFunction.java | 1 + .../common/graph/StandardMutableGraph.java | 3 +- .../common/graph/StandardMutableNetwork.java | 7 +- .../graph/StandardMutableValueGraph.java | 15 +- .../google/common/graph/StandardNetwork.java | 18 +- .../common/graph/StandardValueGraph.java | 41 +- .../common/graph/SuccessorsFunction.java | 1 + .../com/google/common/graph/Traverser.java | 47 +- .../graph/UndirectedGraphConnections.java | 15 +- .../UndirectedMultiNetworkConnections.java | 12 +- .../graph/UndirectedNetworkConnections.java | 5 +- .../com/google/common/graph/ValueGraph.java | 13 +- .../common/graph/ValueGraphBuilder.java | 1 + .../common/hash/AbstractByteHasher.java | 1 + .../hash/AbstractCompositeHashFunction.java | 7 +- .../common/hash/AbstractHashFunction.java | 5 +- .../google/common/hash/AbstractHasher.java | 5 +- .../AbstractNonStreamingHashFunction.java | 1 + .../common/hash/AbstractStreamingHasher.java | 1 + .../com/google/common/hash/BloomFilter.java | 59 +- .../common/hash/BloomFilterStrategies.java | 77 +- .../common/hash/ChecksumHashFunction.java | 1 + .../common/hash/Crc32cHashFunction.java | 1 + .../hash/ElementTypesAreNonnullByDefault.java | 41 + .../common/hash/FarmHashFingerprint64.java | 3 +- .../google/common/hash/Fingerprint2011.java | 198 +++ .../src/com/google/common/hash/Funnel.java | 6 +- .../src/com/google/common/hash/Funnels.java | 16 +- .../src/com/google/common/hash/HashCode.java | 5 +- .../com/google/common/hash/HashFunction.java | 7 +- .../src/com/google/common/hash/Hasher.java | 5 +- .../src/com/google/common/hash/Hashing.java | 90 +- .../common/hash/HashingInputStream.java | 1 + .../common/hash/HashingOutputStream.java | 1 + .../google/common/hash/ImmutableSupplier.java | 2 + .../common/hash/Java8Compatibility.java | 1 + .../common/hash/LittleEndianByteArray.java | 3 +- .../com/google/common/hash/LongAddable.java | 2 + .../com/google/common/hash/LongAddables.java | 4 +- .../src/com/google/common/hash/LongAdder.java | 1 + .../google/common/hash/MacHashFunction.java | 3 +- .../hash/MessageDigestHashFunction.java | 3 +- .../common/hash/Murmur3_128HashFunction.java | 5 +- .../common/hash/Murmur3_32HashFunction.java | 31 +- .../common/hash/ParametricNullness.java | 52 + .../com/google/common/hash/PrimitiveSink.java | 1 + .../google/common/hash/SipHashFunction.java | 5 +- .../src/com/google/common/hash/Striped64.java | 10 +- .../html/ElementTypesAreNonnullByDefault.java | 41 + .../com/google/common/html/HtmlEscapers.java | 1 + .../common/html/ParametricNullness.java | 52 + .../google/common/io/AppendableWriter.java | 13 +- .../com/google/common/io/BaseEncoding.java | 58 +- .../google/common/io/ByteArrayDataInput.java | 3 + .../google/common/io/ByteArrayDataOutput.java | 1 + .../com/google/common/io/ByteProcessor.java | 5 +- .../src/com/google/common/io/ByteSink.java | 1 + .../src/com/google/common/io/ByteSource.java | 21 +- .../src/com/google/common/io/ByteStreams.java | 45 +- .../google/common/io/CharSequenceReader.java | 21 +- .../src/com/google/common/io/CharSink.java | 1 + .../src/com/google/common/io/CharSource.java | 26 +- .../src/com/google/common/io/CharStreams.java | 14 +- .../src/com/google/common/io/Closeables.java | 9 +- .../src/com/google/common/io/Closer.java | 41 +- .../google/common/io/CountingInputStream.java | 1 + .../common/io/CountingOutputStream.java | 1 + .../io/ElementTypesAreNonnullByDefault.java | 41 + .../common/io/FileBackedOutputStream.java | 31 +- .../com/google/common/io/FileWriteMode.java | 1 + .../guava/src/com/google/common/io/Files.java | 85 +- .../src/com/google/common/io/Flushables.java | 1 + .../google/common/io/Java8Compatibility.java | 9 + .../src/com/google/common/io/LineBuffer.java | 1 + .../com/google/common/io/LineProcessor.java | 5 +- .../src/com/google/common/io/LineReader.java | 6 +- .../io/LittleEndianDataInputStream.java | 1 + .../io/LittleEndianDataOutputStream.java | 1 + .../google/common/io/MultiInputStream.java | 8 +- .../src/com/google/common/io/MultiReader.java | 10 +- .../google/common/io/ParametricNullness.java | 52 + .../common/io/PatternFilenameFilter.java | 17 +- .../google/common/io/ReaderInputStream.java | 1 + .../src/com/google/common/io/Resources.java | 11 +- .../google/common/math/BigDecimalMath.java | 1 + .../google/common/math/BigIntegerMath.java | 1 + .../com/google/common/math/DoubleMath.java | 3 +- .../com/google/common/math/DoubleUtils.java | 1 + .../math/ElementTypesAreNonnullByDefault.java | 41 + .../src/com/google/common/math/IntMath.java | 1 + .../common/math/LinearTransformation.java | 6 +- .../src/com/google/common/math/LongMath.java | 3 +- .../google/common/math/MathPreconditions.java | 16 +- .../com/google/common/math/PairedStats.java | 5 +- .../common/math/PairedStatsAccumulator.java | 1 + .../common/math/ParametricNullness.java | 52 + .../src/com/google/common/math/Quantiles.java | 1 + .../src/com/google/common/math/Stats.java | 5 +- .../google/common/math/StatsAccumulator.java | 1 + .../google/common/math/ToDoubleRounder.java | 1 + .../net/ElementTypesAreNonnullByDefault.java | 41 + .../com/google/common/net/HostAndPort.java | 22 +- .../com/google/common/net/HostSpecifier.java | 19 +- .../com/google/common/net/HttpHeaders.java | 187 ++- .../com/google/common/net/InetAddresses.java | 63 +- .../google/common/net/InternetDomainName.java | 17 +- .../src/com/google/common/net/MediaType.java | 38 +- .../google/common/net/ParametricNullness.java | 52 + .../com/google/common/net/PercentEscaper.java | 5 +- .../com/google/common/net/UrlEscapers.java | 1 + .../com/google/common/net/package-info.java | 2 + .../google/common/primitives/Booleans.java | 11 +- .../com/google/common/primitives/Bytes.java | 11 +- .../com/google/common/primitives/Chars.java | 11 +- .../com/google/common/primitives/Doubles.java | 13 +- .../primitives/DoublesMethodsForWeb.java | 1 + .../ElementTypesAreNonnullByDefault.java | 41 + .../com/google/common/primitives/Floats.java | 13 +- .../primitives/FloatsMethodsForWeb.java | 1 + .../primitives/ImmutableDoubleArray.java | 13 +- .../common/primitives/ImmutableIntArray.java | 13 +- .../common/primitives/ImmutableLongArray.java | 13 +- .../com/google/common/primitives/Ints.java | 15 +- .../common/primitives/IntsMethodsForWeb.java | 1 + .../com/google/common/primitives/Longs.java | 15 +- .../common/primitives/ParametricNullness.java | 52 + .../common/primitives/ParseRequest.java | 1 + .../google/common/primitives/Platform.java | 1 + .../google/common/primitives/Primitives.java | 1 + .../com/google/common/primitives/Shorts.java | 11 +- .../primitives/ShortsMethodsForWeb.java | 1 + .../google/common/primitives/SignedBytes.java | 1 + .../common/primitives/UnsignedBytes.java | 9 +- .../common/primitives/UnsignedInteger.java | 5 +- .../common/primitives/UnsignedInts.java | 1 + .../common/primitives/UnsignedLong.java | 28 +- .../common/primitives/UnsignedLongs.java | 1 + .../reflect/AbstractInvocationHandler.java | 14 +- .../com/google/common/reflect/ClassPath.java | 65 +- .../com/google/common/reflect/Element.java | 178 --- .../ElementTypesAreNonnullByDefault.java | 41 + .../reflect/ImmutableTypeToInstanceMap.java | 17 +- .../com/google/common/reflect/Invokable.java | 186 ++- .../reflect/MutableTypeToInstanceMap.java | 53 +- .../com/google/common/reflect/Parameter.java | 20 +- .../common/reflect/ParametricNullness.java | 52 + .../com/google/common/reflect/Reflection.java | 3 +- .../google/common/reflect/TypeCapture.java | 1 + .../google/common/reflect/TypeParameter.java | 17 +- .../google/common/reflect/TypeResolver.java | 25 +- .../common/reflect/TypeToInstanceMap.java | 20 +- .../com/google/common/reflect/TypeToken.java | 93 +- .../google/common/reflect/TypeVisitor.java | 4 +- .../src/com/google/common/reflect/Types.java | 56 +- .../concurrent/AbstractCatchingFuture.java | 38 +- .../AbstractExecutionThreadService.java | 1 + .../util/concurrent/AbstractFuture.java | 260 +++- .../util/concurrent/AbstractIdleService.java | 1 + .../AbstractListeningExecutorService.java | 13 +- .../concurrent/AbstractScheduledService.java | 178 ++- .../util/concurrent/AbstractService.java | 15 +- .../concurrent/AbstractTransformFuture.java | 39 +- .../util/concurrent/AggregateFuture.java | 103 +- .../util/concurrent/AggregateFutureState.java | 41 +- .../common/util/concurrent/AsyncCallable.java | 6 +- .../common/util/concurrent/AsyncFunction.java | 7 +- .../common/util/concurrent/AtomicDouble.java | 2 + .../util/concurrent/AtomicDoubleArray.java | 6 +- .../common/util/concurrent/AtomicLongMap.java | 5 +- .../common/util/concurrent/Atomics.java | 20 +- .../common/util/concurrent/Callables.java | 73 +- .../common/util/concurrent/ClosingFuture.java | 317 +++-- .../util/concurrent/CollectionFuture.java | 34 +- .../util/concurrent/CombinedFuture.java | 47 +- .../concurrent/CycleDetectingLockFactory.java | 39 +- .../util/concurrent/DirectExecutor.java | 1 + .../ElementTypesAreNonnullByDefault.java | 41 + .../util/concurrent/ExecutionError.java | 15 +- .../common/util/concurrent/ExecutionList.java | 10 +- .../util/concurrent/ExecutionSequencer.java | 168 ++- .../util/concurrent/FakeTimeLimiter.java | 10 +- .../common/util/concurrent/FluentFuture.java | 24 +- .../concurrent/ForwardingBlockingDeque.java | 5 + .../concurrent/ForwardingBlockingQueue.java | 3 + .../util/concurrent/ForwardingCondition.java | 1 + .../concurrent/ForwardingExecutorService.java | 18 +- .../concurrent/ForwardingFluentFuture.java | 6 +- .../util/concurrent/ForwardingFuture.java | 10 +- .../ForwardingListenableFuture.java | 8 +- .../ForwardingListeningExecutorService.java | 7 +- .../util/concurrent/ForwardingLock.java | 1 + .../util/concurrent/FutureCallback.java | 7 +- .../common/util/concurrent/Futures.java | 208 +-- .../util/concurrent/FuturesGetChecked.java | 59 +- ...GwtFluentFutureCatchingSpecialization.java | 5 +- .../GwtFuturesCatchingSpecialization.java | 1 + .../util/concurrent/ImmediateFuture.java | 20 +- .../util/concurrent/InterruptibleTask.java | 203 +-- .../util/concurrent/JdkFutureAdapters.java | 43 +- .../util/concurrent/ListenableFuture.java | 19 +- .../util/concurrent/ListenableFutureTask.java | 18 +- .../concurrent/ListenableScheduledFuture.java | 7 +- .../util/concurrent/ListenerCallQueue.java | 3 +- .../concurrent/ListeningExecutorService.java | 11 +- .../ListeningScheduledExecutorService.java | 5 +- .../common/util/concurrent/Monitor.java | 17 +- .../common/util/concurrent/MoreExecutors.java | 82 +- .../common/util/concurrent/NullnessCasts.java | 76 ++ .../OverflowAvoidingLockSupport.java | 5 +- .../util/concurrent/ParametricNullness.java | 52 + .../common/util/concurrent/Partially.java | 1 + .../common/util/concurrent/Platform.java | 5 +- .../common/util/concurrent/RateLimiter.java | 5 +- .../common/util/concurrent/Runnables.java | 1 + .../util/concurrent/SequentialExecutor.java | 10 +- .../common/util/concurrent/Service.java | 46 +- .../util/concurrent/ServiceManager.java | 10 +- .../util/concurrent/ServiceManagerBridge.java | 1 + .../util/concurrent/SettableFuture.java | 12 +- .../util/concurrent/SimpleTimeLimiter.java | 35 +- .../util/concurrent/SmoothRateLimiter.java | 1 + .../common/util/concurrent/Striped.java | 98 +- .../util/concurrent/ThreadFactoryBuilder.java | 28 +- .../common/util/concurrent/TimeLimiter.java | 7 +- .../common/util/concurrent/TimeoutFuture.java | 19 +- .../TrustedListenableFutureTask.java | 56 +- .../concurrent/UncaughtExceptionHandlers.java | 1 + .../UncheckedExecutionException.java | 15 +- .../concurrent/UncheckedTimeoutException.java | 9 +- .../util/concurrent/Uninterruptibles.java | 14 +- .../concurrent/WrappingExecutorService.java | 40 +- .../WrappingScheduledExecutorService.java | 5 +- .../xml/ElementTypesAreNonnullByDefault.java | 41 + .../google/common/xml/ParametricNullness.java | 52 + .../com/google/common/xml/XmlEscapers.java | 3 +- .../publicsuffix/PublicSuffixPatterns.java | 6 +- .../thirdparty/publicsuffix/TrieParser.java | 2 +- android/pom.xml | 104 +- azure-pipelines.yml | 2 +- .../util/concurrent/ListenableFuture.java | 19 +- guava-bom/pom.xml | 2 +- guava-gwt/pom.xml | 8 +- .../com/google/common/cache/LocalCache.java | 2 +- .../collect/ForwardingImmutableMap.java | 4 +- .../google/common/collect/ImmutableBiMap.java | 96 +- .../google/common/collect/ImmutableMap.java | 151 ++- .../google/common/collect/ImmutableSet.java | 19 + .../common/collect/ImmutableSortedMap.java | 126 ++ .../com/google/common/collect/Platform.java | 10 + .../common/collect/RegularImmutableMap.java | 6 +- .../util/concurrent/AbstractFuture.java | 3 + .../GwtFuturesCatchingSpecialization.java | 20 - .../util/concurrent/InterruptibleTask.java | 19 +- .../common/annotations/Annotations.gwt.xml | 37 +- .../src/com/google/common/base/Base.gwt.xml | 39 +- .../src/com/google/common/cache/Cache.gwt.xml | 38 +- .../com/google/common/collect/Collect.gwt.xml | 39 +- .../com/google/common/escape/Escape.gwt.xml | 38 +- .../src/com/google/common/html/Html.gwt.xml | 36 +- guava-gwt/src/com/google/common/io/Io.gwt.xml | 38 +- .../src/com/google/common/math/Math.gwt.xml | 38 +- .../src/com/google/common/net/Net.gwt.xml | 41 +- .../common/primitives/Primitives.gwt.xml | 39 +- .../common/util/concurrent/Concurrent.gwt.xml | 40 +- .../src/com/google/common/xml/Xml.gwt.xml | 36 +- .../publicsuffix/PublicSuffixPatterns.gwt.xml | 37 +- .../publicsuffix/PublicSuffixType.gwt.xml | 35 +- .../common/collect/testing/Testing.gwt.xml | 40 +- .../collect/testing/google/Google.gwt.xml | 40 +- .../common/escape/testing/Testing.gwt.xml | 37 +- .../com/google/common/testing/Testing.gwt.xml | 40 +- guava-testlib/README.md | 4 +- guava-testlib/pom.xml | 2 +- .../testing/AbstractContainerTester.java | 4 +- .../collect/testing/AbstractMapTester.java | 8 +- .../testing/CollectionTestSuiteBuilder.java | 2 + .../testing/DerivedCollectionGenerators.java | 13 +- .../FeatureSpecificTestSuiteBuilder.java | 20 +- .../common/collect/testing/Helpers.java | 18 +- .../collect/testing/ListTestSuiteBuilder.java | 2 + .../collect/testing/MapInterfaceTest.java | 212 +-- .../collect/testing/MapTestSuiteBuilder.java | 8 + .../collect/testing/MinimalCollection.java | 4 +- .../collect/testing/MinimalIterable.java | 4 +- .../common/collect/testing/MinimalSet.java | 4 +- .../testing/NavigableMapTestSuiteBuilder.java | 4 +- .../testing/NavigableSetTestSuiteBuilder.java | 9 +- .../collect/testing/OneSizeGenerator.java | 2 +- .../ReserializingTestCollectionGenerator.java | 2 +- .../ReserializingTestSetGenerator.java | 2 +- .../common/collect/testing/SafeTreeSet.java | 8 +- .../collect/testing/SetTestSuiteBuilder.java | 2 + .../testing/SortedMapInterfaceTest.java | 6 +- .../testing/SortedMapTestSuiteBuilder.java | 10 +- .../testing/SortedSetTestSuiteBuilder.java | 13 +- .../collect/testing/SpliteratorTester.java | 3 +- .../collect/testing/features/FeatureUtil.java | 8 +- .../google/AbstractMultimapTester.java | 10 +- .../testing/google/BiMapTestSuiteBuilder.java | 6 + .../DerivedGoogleCollectionGenerators.java | 6 +- .../collect/testing/google/MapGenerators.java | 12 +- .../google/MultimapTestSuiteBuilder.java | 12 + .../google/MultisetNavigationTester.java | 2 +- .../google/MultisetTestSuiteBuilder.java | 6 + .../google/SetMultimapAsMapTester.java | 2 +- .../SortedMultisetTestSuiteBuilder.java | 18 +- .../google/SortedSetMultimapAsMapTester.java | 2 +- .../google/UnmodifiableCollectionTests.java | 4 +- .../testers/CollectionForEachTester.java | 4 +- .../testers/CollectionIteratorTester.java | 6 +- .../testers/CollectionToArrayTester.java | 4 +- .../testing/testers/MapReplaceAllTester.java | 4 +- .../testers/NavigableSetNavigationTester.java | 2 +- .../common/escape/testing/EscaperAsserts.java | 2 - .../testing/AbstractPackageSanityTests.java | 20 +- .../common/testing/ArbitraryInstances.java | 4 +- .../common/testing/CollectorTester.java | 2 - .../google/common/testing/EqualsTester.java | 4 +- .../common/testing/EquivalenceTester.java | 7 +- .../com/google/common/testing/FakeTicker.java | 2 - .../testing/ForwardingWrapperTester.java | 6 +- .../common/testing/FreshValueGenerator.java | 242 ++-- .../google/common/testing/GcFinalization.java | 35 +- .../common/testing/NullPointerTester.java | 52 +- .../common/testing/RelationshipTester.java | 2 +- .../common/testing/SerializableTester.java | 3 - .../google/common/testing/TestLogHandler.java | 2 - .../testing/AbstractListenableFutureTest.java | 109 +- .../testing/MockFutureListener.java | 8 +- .../SameThreadScheduledExecutorService.java | 4 +- .../concurrent/testing/TestingExecutors.java | 6 +- .../FeatureSpecificTestSuiteBuilderTest.java | 6 +- .../testing/MapTestSuiteBuilderTests.java | 92 ++ .../common/testing/EquivalenceTesterTest.java | 2 +- .../common/testing/NullPointerTesterTest.java | 43 + .../common/base/StringsRepeatBenchmark.java | 6 +- .../common/base/ToStringHelperBenchmark.java | 2 + ...ableSetHashFloodingDetectionBenchmark.java | 44 + .../google/common/collect/MapBenchmark.java | 2 +- .../FuturesGetCheckedBenchmark.java | 7 +- .../MonitorBasedArrayBlockingQueue.java | 66 +- .../MonitorBasedPriorityBlockingQueue.java | 60 +- guava-tests/pom.xml | 5 +- .../common/base/AbstractIteratorTest.java | 2 +- .../com/google/common/base/AsciiTest.java | 13 +- .../google/common/base/CharMatcherTest.java | 2 +- .../com/google/common/base/OptionalTest.java | 6 + .../google/common/base/PreconditionsTest.java | 19 +- .../common/base/StopwatchJavaTimeTest.java | 37 + .../com/google/common/base/StopwatchTest.java | 11 - .../common/base/ToStringHelperTest.java | 38 +- .../com/google/common/base/VerifyTest.java | 8 +- .../google/common/cache/LocalCacheTest.java | 2 +- .../common/collect/AbstractIteratorTest.java | 1 + .../common/collect/AbstractMapEntryTest.java | 3 +- .../collect/CompactHashMapFloodingTest.java | 28 + .../common/collect/CompactHashMapTest.java | 9 - .../collect/CompactHashSetFloodingTest.java | 28 + .../common/collect/CompactHashSetTest.java | 9 - .../CompactLinkedHashMapFloodingTest.java | 21 +- .../collect/CompactLinkedHashMapTest.java | 9 - .../CompactLinkedHashSetFloodingTest.java | 28 + .../collect/CompactLinkedHashSetTest.java | 9 - .../common/collect/DiscreteDomainTest.java | 44 + .../common/collect/ForwardingMapTest.java | 2 +- .../common/collect/ImmutableBiMapTest.java | 173 ++- .../collect/ImmutableListMultimapTest.java | 10 + .../common/collect/ImmutableMapTest.java | 478 ++++++- .../common/collect/ImmutableMultimapTest.java | 11 + .../common/collect/ImmutableRangeSetTest.java | 4 + .../collect/ImmutableSetMultimapTest.java | 10 + .../common/collect/ImmutableSetTest.java | 6 + .../collect/ImmutableSortedMapTest.java | 140 +- .../collect/ImmutableSortedSetTest.java | 2 +- .../google/common/collect/IteratorsTest.java | 4 + .../com/google/common/collect/ListsTest.java | 16 +- .../google/common/collect/MapMakerTest.java | 41 +- .../com/google/common/collect/MapsTest.java | 100 +- .../common/collect/MoreCollectorsTest.java | 8 + .../google/common/collect/MultimapsTest.java | 3 +- .../com/google/common/collect/RangeTest.java | 10 + .../collect/RegularImmutableAsListTest.java | 3 +- .../common/collect/SetOperationsTest.java | 166 ++- .../com/google/common/collect/SetsTest.java | 1 + .../common/collect/SynchronizedDequeTest.java | 5 +- .../common/collect/SynchronizedMapTest.java | 10 +- .../common/collect/SynchronizedQueueTest.java | 5 +- .../common/collect/TableCollectorsTest.java | 407 +++--- .../common/collect/TopKSelectorTest.java | 11 + .../collect/UnmodifiableIteratorTest.java | 1 + .../collect/UnmodifiableListIteratorTest.java | 3 + .../google/common/escape/EscapersTest.java | 2 +- .../outside/AbstractEventBusTest.java | 55 + .../AbstractNotAnnotatedInSuperclassTest.java | 61 + .../AnnotatedAndAbstractInSuperclassTest.java | 63 + .../AnnotatedNotAbstractInSuperclassTest.java | 116 ++ .../AnnotatedSubscriberFinderTests.java | 448 ------- .../outside/BaseSubscriberFinderTest.java | 53 + .../eventbus/outside/DeepInterfaceTest.java | 153 +++ ...rAbstractNorAnnotatedInSuperclassTest.java | 74 ++ .../com/google/common/graph/MapCacheTest.java | 21 - .../google/common/hash/BloomFilterTest.java | 5 +- .../common/hash/Fingerprint2011Test.java | 233 ++++ .../google/common/hash/HashFunctionEnum.java | 1 + .../com/google/common/hash/HashTestUtils.java | 4 +- .../com/google/common/hash/HashingTest.java | 19 +- .../google/common/hash/Murmur3Hash32Test.java | 79 +- .../com/google/common/io/ByteSourceTest.java | 3 +- .../google/common/io/ByteSourceTester.java | 2 +- .../com/google/common/io/ByteStreamsTest.java | 41 +- .../common/io/CharSequenceReaderTest.java | 6 +- .../com/google/common/io/CharSourceTest.java | 3 +- .../test/com/google/common/io/CloserTest.java | 6 +- .../io/LittleEndianDataInputStreamTest.java | 1 + .../com/google/common/io/MoreFilesTest.java | 12 + .../common/io/PatternFilenameFilterTest.java | 13 + .../google/common/io/SourceSinkFactories.java | 4 +- .../google/common/io/SourceSinkTester.java | 2 +- .../com/google/common/math/IntMathTest.java | 7 +- .../common/math/MathPreconditionsTest.java | 11 + .../common/math/QuantilesAlgorithm.java | 4 +- .../com/google/common/math/QuantilesTest.java | 6 +- .../google/common/net/HostAndPortTest.java | 7 + .../google/common/net/HostSpecifierTest.java | 5 +- .../google/common/net/HttpHeadersTest.java | 4 +- .../google/common/net/InetAddressesTest.java | 28 + .../common/net/InternetDomainNameTest.java | 4 +- .../com/google/common/net/MediaTypeTest.java | 3 +- .../google/common/net/PercentEscaperTest.java | 13 +- .../common/primitives/BooleansTest.java | 3 +- .../common/primitives/UnsignedLongTest.java | 25 +- .../google/common/reflect/ElementTest.java | 247 ---- .../google/common/reflect/InvokableTest.java | 193 ++- .../google/common/reflect/TypeTokenTest.java | 16 +- .../AbstractAbstractFutureTest.java | 1 - ...st.java => AbstractClosingFutureTest.java} | 193 +-- .../AbstractExecutionThreadServiceTest.java | 9 - .../AbstractFutureCancellationCauseTest.java | 1 + .../util/concurrent/AbstractFutureTest.java | 2 +- .../concurrent/AbstractIdleServiceTest.java | 1 - .../AbstractScheduledServiceTest.java | 90 +- .../util/concurrent/AbstractServiceTest.java | 9 - .../concurrent/AtomicDoubleArrayTest.java | 138 +- .../util/concurrent/AtomicDoubleTest.java | 107 +- .../concurrent/AtomicLongMapBasherTest.java | 34 +- .../util/concurrent/AtomicLongMapTest.java | 6 +- .../ClosingFutureFinishToFutureTest.java | 94 ++ ...osingFutureFinishToValueAndCloserTest.java | 148 +++ .../CycleDetectingLockFactoryTest.java | 3 - .../util/concurrent/ExecutionListTest.java | 3 - .../concurrent/ExecutionSequencerTest.java | 3 - .../util/concurrent/FluentFutureTest.java | 1 - .../concurrent/ForwardingObjectTester.java | 2 +- .../concurrent/FuturesGetCheckedTest.java | 5 +- .../common/util/concurrent/FuturesTest.java | 31 +- .../concurrent/FuturesTransformAsyncTest.java | 1 - .../util/concurrent/GeneratedMonitorTest.java | 1 - .../concurrent/InterruptibleMonitorTest.java | 1 - .../concurrent/InterruptibleTaskTest.java | 54 +- .../util/concurrent/JSR166TestCase.java | 2 +- .../concurrent/JdkFutureAdaptersTest.java | 3 - .../concurrent/ListenableFutureTaskTest.java | 3 - .../concurrent/ListenerCallQueueTest.java | 2 - .../util/concurrent/MonitorTestCase.java | 1 - .../util/concurrent/MoreExecutorsTest.java | 32 +- .../concurrent/SequentialExecutorTest.java | 10 +- .../util/concurrent/ServiceManagerTest.java | 32 +- .../util/concurrent/SettableFutureTest.java | 4 - .../concurrent/SimpleTimeLimiterTest.java | 1 - .../common/util/concurrent/StripedTest.java | 6 +- .../concurrent/SupplementalMonitorTest.java | 1 - .../concurrent/ThreadFactoryBuilderTest.java | 10 - .../TrustedListenableFutureTaskTest.java | 3 - .../UncaughtExceptionHandlersTest.java | 1 - .../concurrent/UninterruptibleFutureTest.java | 11 - .../UninterruptibleMonitorTest.java | 1 - .../util/concurrent/UninterruptiblesTest.java | 1 - guava/pom.xml | 78 +- guava/src/com/google/common/base/Absent.java | 7 +- .../google/common/base/AbstractIterator.java | 15 +- guava/src/com/google/common/base/Ascii.java | 19 +- .../com/google/common/base/CaseFormat.java | 15 +- .../com/google/common/base/CharMatcher.java | 7 +- .../src/com/google/common/base/Charsets.java | 1 + .../com/google/common/base/CommonMatcher.java | 1 + .../com/google/common/base/CommonPattern.java | 1 + .../src/com/google/common/base/Converter.java | 157 ++- .../src/com/google/common/base/Defaults.java | 47 +- .../base/ElementTypesAreNonnullByDefault.java | 41 + guava/src/com/google/common/base/Enums.java | 8 +- .../com/google/common/base/Equivalence.java | 84 +- .../base/ExtraObjectsMethodsForWeb.java | 1 + .../base/FinalizablePhantomReference.java | 4 +- .../common/base/FinalizableReference.java | 1 + .../base/FinalizableReferenceQueue.java | 16 +- .../common/base/FinalizableSoftReference.java | 4 +- .../common/base/FinalizableWeakReference.java | 4 +- .../src/com/google/common/base/Function.java | 11 +- .../common/base/FunctionalEquivalence.java | 9 +- .../src/com/google/common/base/Functions.java | 101 +- .../common/base/Java8Compatibility.java | 44 + .../com/google/common/base/Java8Usage.java | 45 - .../com/google/common/base/JdkPattern.java | 1 + guava/src/com/google/common/base/Joiner.java | 75 +- .../com/google/common/base/MoreObjects.java | 125 +- .../com/google/common/base/NullnessCasts.java | 60 + guava/src/com/google/common/base/Objects.java | 6 +- .../src/com/google/common/base/Optional.java | 28 +- .../common/base/PairwiseEquivalence.java | 14 +- .../common/base/ParametricNullness.java | 52 + .../google/common/base/PatternCompiler.java | 1 + .../src/com/google/common/base/Platform.java | 12 +- .../com/google/common/base/Preconditions.java | 309 +++-- .../src/com/google/common/base/Predicate.java | 10 +- .../com/google/common/base/Predicates.java | 137 +- guava/src/com/google/common/base/Present.java | 7 +- .../google/common/base/SmallCharMatcher.java | 3 +- .../src/com/google/common/base/Splitter.java | 12 +- .../common/base/StandardSystemProperty.java | 6 +- .../src/com/google/common/base/Stopwatch.java | 3 +- guava/src/com/google/common/base/Strings.java | 20 +- .../src/com/google/common/base/Supplier.java | 5 +- .../src/com/google/common/base/Suppliers.java | 87 +- .../com/google/common/base/Throwables.java | 65 +- guava/src/com/google/common/base/Ticker.java | 1 + guava/src/com/google/common/base/Utf8.java | 10 +- guava/src/com/google/common/base/Verify.java | 100 +- .../google/common/base/VerifyException.java | 9 +- .../common/base/internal/Finalizer.java | 21 +- .../google/common/cache/AbstractCache.java | 10 +- .../common/cache/AbstractLoadingCache.java | 1 + guava/src/com/google/common/cache/Cache.java | 16 +- .../com/google/common/cache/CacheBuilder.java | 75 +- .../google/common/cache/CacheBuilderSpec.java | 63 +- .../com/google/common/cache/CacheLoader.java | 1 + .../com/google/common/cache/CacheStats.java | 5 +- .../ElementTypesAreNonnullByDefault.java | 41 + .../google/common/cache/ForwardingCache.java | 15 +- .../common/cache/ForwardingLoadingCache.java | 1 + .../com/google/common/cache/LoadingCache.java | 3 + .../com/google/common/cache/LocalCache.java | 22 +- .../com/google/common/cache/LongAddable.java | 1 + .../com/google/common/cache/LongAddables.java | 4 +- .../com/google/common/cache/LongAdder.java | 1 + .../common/cache/ParametricNullness.java | 52 + .../google/common/cache/ReferenceEntry.java | 8 +- .../com/google/common/cache/RemovalCause.java | 1 + .../google/common/cache/RemovalListener.java | 1 + .../google/common/cache/RemovalListeners.java | 17 +- .../common/cache/RemovalNotification.java | 11 +- .../com/google/common/cache/Striped64.java | 8 +- .../src/com/google/common/cache/Weigher.java | 1 + .../google/common/collect/AbstractBiMap.java | 100 +- .../collect/AbstractIndexedListIterator.java | 8 +- .../common/collect/AbstractIterator.java | 17 +- .../common/collect/AbstractListMultimap.java | 21 +- .../collect/AbstractMapBasedMultimap.java | 274 ++-- .../collect/AbstractMapBasedMultiset.java | 42 +- .../common/collect/AbstractMapEntry.java | 12 +- .../common/collect/AbstractMultimap.java | 33 +- .../common/collect/AbstractMultiset.java | 25 +- .../common/collect/AbstractNavigableMap.java | 53 +- .../common/collect/AbstractRangeSet.java | 6 +- .../collect/AbstractSequentialIterator.java | 20 +- .../common/collect/AbstractSetMultimap.java | 21 +- .../AbstractSortedKeySortedSetMultimap.java | 6 +- .../collect/AbstractSortedMultiset.java | 17 +- .../collect/AbstractSortedSetMultimap.java | 17 +- .../google/common/collect/AbstractTable.java | 37 +- .../common/collect/AllEqualOrdering.java | 13 +- .../common/collect/ArrayListMultimap.java | 15 +- .../com/google/common/collect/ArrayTable.java | 174 ++- .../common/collect/BaseImmutableMultimap.java | 1 + .../src/com/google/common/collect/BiMap.java | 20 +- .../com/google/common/collect/BoundType.java | 5 +- .../common/collect/ByFunctionOrdering.java | 9 +- .../google/common/collect/CartesianList.java | 13 +- .../common/collect/ClassToInstanceMap.java | 23 +- .../common/collect/CollectCollectors.java | 159 ++- .../common/collect/CollectPreconditions.java | 1 + .../common/collect/CollectSpliterators.java | 103 +- .../google/common/collect/Collections2.java | 51 +- .../google/common/collect/CompactHashMap.java | 437 +++++-- .../google/common/collect/CompactHashSet.java | 192 ++- .../google/common/collect/CompactHashing.java | 22 +- .../common/collect/CompactLinkedHashMap.java | 69 +- .../common/collect/CompactLinkedHashSet.java | 71 +- .../common/collect/ComparatorOrdering.java | 9 +- .../google/common/collect/Comparators.java | 39 +- .../common/collect/ComparisonChain.java | 35 +- .../common/collect/CompoundOrdering.java | 9 +- .../common/collect/ComputationException.java | 4 +- .../collect/ConcurrentHashMultiset.java | 42 +- .../collect/ConsumingQueueIterator.java | 19 +- .../google/common/collect/ContiguousSet.java | 24 +- .../src/com/google/common/collect/Count.java | 5 +- guava/src/com/google/common/collect/Cut.java | 39 +- .../common/collect/DenseImmutableTable.java | 32 +- .../DescendingImmutableSortedMultiset.java | 7 +- .../collect/DescendingImmutableSortedSet.java | 11 +- .../common/collect/DescendingMultiset.java | 31 +- .../google/common/collect/DiscreteDomain.java | 20 +- .../ElementTypesAreNonnullByDefault.java | 41 + .../common/collect/EmptyContiguousSet.java | 13 +- .../collect/EmptyImmutableListMultimap.java | 1 + .../collect/EmptyImmutableSetMultimap.java | 1 + .../com/google/common/collect/EnumBiMap.java | 3 +- .../google/common/collect/EnumHashBiMap.java | 23 +- .../google/common/collect/EnumMultiset.java | 19 +- .../google/common/collect/EvictingQueue.java | 27 +- .../common/collect/ExplicitOrdering.java | 4 +- .../common/collect/FilteredEntryMultimap.java | 48 +- .../collect/FilteredEntrySetMultimap.java | 13 +- .../collect/FilteredKeyListMultimap.java | 12 +- .../common/collect/FilteredKeyMultimap.java | 39 +- .../collect/FilteredKeySetMultimap.java | 14 +- .../common/collect/FilteredMultimap.java | 5 +- .../collect/FilteredMultimapValues.java | 9 +- .../common/collect/FilteredSetMultimap.java | 5 +- .../google/common/collect/FluentIterable.java | 74 +- .../collect/ForwardingBlockingDeque.java | 5 + .../common/collect/ForwardingCollection.java | 30 +- .../collect/ForwardingConcurrentMap.java | 9 +- .../common/collect/ForwardingDeque.java | 29 +- .../ForwardingImmutableCollection.java | 1 + .../collect/ForwardingImmutableList.java | 1 + .../collect/ForwardingImmutableMap.java | 1 + .../collect/ForwardingImmutableSet.java | 1 + .../common/collect/ForwardingIterator.java | 7 +- .../google/common/collect/ForwardingList.java | 29 +- .../collect/ForwardingListIterator.java | 14 +- .../collect/ForwardingListMultimap.java | 12 +- .../google/common/collect/ForwardingMap.java | 39 +- .../common/collect/ForwardingMapEntry.java | 15 +- .../common/collect/ForwardingMultimap.java | 25 +- .../common/collect/ForwardingMultiset.java | 31 +- .../collect/ForwardingNavigableMap.java | 91 +- .../collect/ForwardingNavigableSet.java | 58 +- .../common/collect/ForwardingObject.java | 1 + .../common/collect/ForwardingQueue.java | 16 +- .../google/common/collect/ForwardingSet.java | 9 +- .../common/collect/ForwardingSetMultimap.java | 12 +- .../common/collect/ForwardingSortedMap.java | 40 +- .../collect/ForwardingSortedMultiset.java | 29 +- .../common/collect/ForwardingSortedSet.java | 50 +- .../collect/ForwardingSortedSetMultimap.java | 14 +- .../common/collect/ForwardingTable.java | 31 +- .../google/common/collect/GeneralRange.java | 93 +- .../google/common/collect/GwtTransient.java | 1 + .../google/common/collect/HashBasedTable.java | 43 +- .../com/google/common/collect/HashBiMap.java | 131 +- .../google/common/collect/HashMultimap.java | 16 +- .../google/common/collect/HashMultiset.java | 10 +- .../com/google/common/collect/Hashing.java | 4 +- .../common/collect/ImmutableAsList.java | 4 +- .../google/common/collect/ImmutableBiMap.java | 226 +++- .../collect/ImmutableBiMapFauxverideShim.java | 21 +- .../collect/ImmutableClassToInstanceMap.java | 16 +- .../common/collect/ImmutableCollection.java | 28 +- .../google/common/collect/ImmutableEntry.java | 19 +- .../common/collect/ImmutableEnumMap.java | 10 +- .../common/collect/ImmutableEnumSet.java | 6 +- .../google/common/collect/ImmutableList.java | 67 +- .../common/collect/ImmutableListMultimap.java | 29 +- .../google/common/collect/ImmutableMap.java | 444 +++++-- .../common/collect/ImmutableMapEntry.java | 36 +- .../common/collect/ImmutableMapEntrySet.java | 8 +- .../common/collect/ImmutableMapKeySet.java | 5 +- .../common/collect/ImmutableMapValues.java | 5 +- .../common/collect/ImmutableMultimap.java | 66 +- .../common/collect/ImmutableMultiset.java | 52 +- ...eMultisetGwtSerializationDependencies.java | 1 + .../common/collect/ImmutableRangeMap.java | 22 +- .../common/collect/ImmutableRangeSet.java | 23 +- .../google/common/collect/ImmutableSet.java | 385 ++++-- .../common/collect/ImmutableSetMultimap.java | 52 +- .../common/collect/ImmutableSortedAsList.java | 10 +- .../common/collect/ImmutableSortedMap.java | 301 ++++- .../ImmutableSortedMapFauxverideShim.java | 176 ++- .../collect/ImmutableSortedMultiset.java | 29 +- ...ImmutableSortedMultisetFauxverideShim.java | 19 +- .../common/collect/ImmutableSortedSet.java | 31 +- .../ImmutableSortedSetFauxverideShim.java | 14 +- .../google/common/collect/ImmutableTable.java | 63 +- .../common/collect/IndexedImmutableSet.java | 6 +- .../com/google/common/collect/Interner.java | 3 +- .../com/google/common/collect/Interners.java | 20 +- .../com/google/common/collect/Iterables.java | 157 ++- .../com/google/common/collect/Iterators.java | 254 ++-- .../collect/JdkBackedImmutableBiMap.java | 20 +- .../common/collect/JdkBackedImmutableMap.java | 56 +- .../collect/JdkBackedImmutableMultiset.java | 9 +- .../common/collect/JdkBackedImmutableSet.java | 5 +- .../collect/LexicographicalOrdering.java | 7 +- .../common/collect/LinkedHashMultimap.java | 140 +- .../common/collect/LinkedHashMultiset.java | 14 +- .../common/collect/LinkedListMultimap.java | 181 +-- .../google/common/collect/ListMultimap.java | 16 +- .../src/com/google/common/collect/Lists.java | 176 +-- .../google/common/collect/MapDifference.java | 12 +- .../com/google/common/collect/MapMaker.java | 8 +- .../common/collect/MapMakerInternalMap.java | 6 +- guava/src/com/google/common/collect/Maps.java | 1142 +++++++++++------ .../common/collect/MinMaxPriorityQueue.java | 53 +- .../google/common/collect/MoreCollectors.java | 36 +- .../com/google/common/collect/Multimap.java | 29 +- .../common/collect/MultimapBuilder.java | 104 +- .../com/google/common/collect/Multimaps.java | 360 ++++-- .../com/google/common/collect/Multiset.java | 34 +- .../com/google/common/collect/Multisets.java | 163 ++- .../collect/MutableClassToInstanceMap.java | 26 +- .../common/collect/NaturalOrdering.java | 30 +- .../google/common/collect/NullnessCasts.java | 68 + .../common/collect/NullsFirstOrdering.java | 20 +- .../common/collect/NullsLastOrdering.java | 20 +- .../google/common/collect/ObjectArrays.java | 23 +- .../com/google/common/collect/Ordering.java | 48 +- .../common/collect/ParametricNullness.java | 52 + .../common/collect/PeekingIterator.java | 8 +- .../com/google/common/collect/Platform.java | 42 +- .../src/com/google/common/collect/Queues.java | 18 +- .../src/com/google/common/collect/Range.java | 26 +- .../com/google/common/collect/RangeMap.java | 38 +- .../com/google/common/collect/RangeSet.java | 10 +- .../common/collect/RegularContiguousSet.java | 29 +- .../collect/RegularImmutableAsList.java | 7 +- .../common/collect/RegularImmutableBiMap.java | 70 +- .../common/collect/RegularImmutableList.java | 3 +- .../common/collect/RegularImmutableMap.java | 181 ++- .../collect/RegularImmutableMultiset.java | 56 +- .../common/collect/RegularImmutableSet.java | 29 +- .../RegularImmutableSortedMultiset.java | 7 +- .../collect/RegularImmutableSortedSet.java | 15 +- .../common/collect/RegularImmutableTable.java | 38 +- .../collect/ReverseNaturalOrdering.java | 25 +- .../common/collect/ReverseOrdering.java | 19 +- .../google/common/collect/RowSortedTable.java | 6 +- .../google/common/collect/Serialization.java | 35 +- .../google/common/collect/SetMultimap.java | 19 +- guava/src/com/google/common/collect/Sets.java | 287 +++-- .../collect/SingletonImmutableBiMap.java | 14 +- .../collect/SingletonImmutableList.java | 3 +- .../common/collect/SingletonImmutableSet.java | 39 +- .../collect/SingletonImmutableTable.java | 1 + .../google/common/collect/SortedIterable.java | 4 +- .../common/collect/SortedIterables.java | 5 +- .../google/common/collect/SortedLists.java | 56 +- .../common/collect/SortedMapDifference.java | 5 +- .../google/common/collect/SortedMultiset.java | 22 +- .../common/collect/SortedMultisetBridge.java | 4 +- .../common/collect/SortedMultisets.java | 53 +- .../common/collect/SortedSetMultimap.java | 21 +- .../common/collect/SparseImmutableTable.java | 20 +- .../collect/StandardRowSortedTable.java | 3 + .../google/common/collect/StandardTable.java | 198 ++- .../com/google/common/collect/Streams.java | 140 +- .../google/common/collect/Synchronized.java | 430 ++++--- .../src/com/google/common/collect/Table.java | 50 +- .../common/collect/TableCollectors.java | 69 +- .../src/com/google/common/collect/Tables.java | 187 ++- .../google/common/collect/TopKSelector.java | 44 +- .../common/collect/TransformedIterator.java | 9 +- .../collect/TransformedListIterator.java | 11 +- .../google/common/collect/TreeBasedTable.java | 73 +- .../google/common/collect/TreeMultimap.java | 19 +- .../google/common/collect/TreeMultiset.java | 240 ++-- .../google/common/collect/TreeRangeMap.java | 90 +- .../google/common/collect/TreeRangeSet.java | 79 +- .../google/common/collect/TreeTraverser.java | 3 + .../common/collect/UnmodifiableIterator.java | 4 +- .../collect/UnmodifiableListIterator.java | 10 +- .../collect/UnmodifiableSortedMultiset.java | 21 +- .../common/collect/UsingToStringOrdering.java | 1 + .../common/escape/ArrayBasedCharEscaper.java | 9 +- .../common/escape/ArrayBasedEscaperMap.java | 11 +- .../escape/ArrayBasedUnicodeEscaper.java | 8 +- .../com/google/common/escape/CharEscaper.java | 18 +- .../common/escape/CharEscaperBuilder.java | 17 +- .../ElementTypesAreNonnullByDefault.java | 41 + .../src/com/google/common/escape/Escaper.java | 9 +- .../com/google/common/escape/Escapers.java | 18 +- .../common/escape/ParametricNullness.java | 52 + .../com/google/common/escape/Platform.java | 1 + .../google/common/escape/UnicodeEscaper.java | 5 +- .../eventbus/AllowConcurrentEvents.java | 3 +- .../google/common/eventbus/AsyncEventBus.java | 3 +- .../com/google/common/eventbus/DeadEvent.java | 3 +- .../google/common/eventbus/Dispatcher.java | 1 + .../ElementTypesAreNonnullByDefault.java | 41 + .../com/google/common/eventbus/EventBus.java | 61 +- .../common/eventbus/ParametricNullness.java | 52 + .../com/google/common/eventbus/Subscribe.java | 3 +- .../google/common/eventbus/Subscriber.java | 20 +- .../eventbus/SubscriberExceptionContext.java | 5 +- .../eventbus/SubscriberExceptionHandler.java | 2 + .../common/eventbus/SubscriberRegistry.java | 5 +- .../common/graph/AbstractBaseGraph.java | 29 +- .../AbstractDirectedNetworkConnections.java | 22 +- .../google/common/graph/AbstractGraph.java | 5 +- .../common/graph/AbstractGraphBuilder.java | 1 + .../google/common/graph/AbstractNetwork.java | 13 +- .../AbstractUndirectedNetworkConnections.java | 14 +- .../common/graph/AbstractValueGraph.java | 10 +- .../com/google/common/graph/BaseGraph.java | 1 + .../graph/DirectedGraphConnections.java | 91 +- .../DirectedMultiNetworkConnections.java | 12 +- .../graph/DirectedNetworkConnections.java | 6 +- .../google/common/graph/EdgesConnecting.java | 8 +- .../com/google/common/graph/ElementOrder.java | 20 +- .../ElementTypesAreNonnullByDefault.java | 41 + .../com/google/common/graph/EndpointPair.java | 16 +- .../common/graph/EndpointPairIterator.java | 30 +- .../google/common/graph/ForwardingGraph.java | 3 +- .../common/graph/ForwardingNetwork.java | 6 +- .../common/graph/ForwardingValueGraph.java | 11 +- guava/src/com/google/common/graph/Graph.java | 5 +- .../com/google/common/graph/GraphBuilder.java | 3 +- .../google/common/graph/GraphConnections.java | 7 +- .../google/common/graph/GraphConstants.java | 10 +- guava/src/com/google/common/graph/Graphs.java | 35 +- .../google/common/graph/ImmutableGraph.java | 5 +- .../google/common/graph/ImmutableNetwork.java | 34 +- .../common/graph/ImmutableValueGraph.java | 18 +- .../google/common/graph/IncidentEdgeSet.java | 11 +- .../google/common/graph/MapIteratorCache.java | 46 +- .../common/graph/MapRetrievalCache.java | 22 +- .../common/graph/MultiEdgesConnecting.java | 8 +- .../com/google/common/graph/MutableGraph.java | 1 + .../google/common/graph/MutableNetwork.java | 1 + .../common/graph/MutableValueGraph.java | 6 + .../src/com/google/common/graph/Network.java | 9 +- .../google/common/graph/NetworkBuilder.java | 1 + .../common/graph/NetworkConnections.java | 3 + .../common/graph/ParametricNullness.java | 52 + .../common/graph/PredecessorsFunction.java | 1 + .../common/graph/StandardMutableGraph.java | 3 +- .../common/graph/StandardMutableNetwork.java | 7 +- .../graph/StandardMutableValueGraph.java | 15 +- .../google/common/graph/StandardNetwork.java | 18 +- .../common/graph/StandardValueGraph.java | 39 +- .../common/graph/SuccessorsFunction.java | 1 + .../com/google/common/graph/Traverser.java | 48 +- .../graph/UndirectedGraphConnections.java | 15 +- .../UndirectedMultiNetworkConnections.java | 11 +- .../graph/UndirectedNetworkConnections.java | 5 +- .../com/google/common/graph/ValueGraph.java | 13 +- .../common/graph/ValueGraphBuilder.java | 1 + .../common/hash/AbstractByteHasher.java | 7 +- .../hash/AbstractCompositeHashFunction.java | 7 +- .../common/hash/AbstractHashFunction.java | 10 +- .../google/common/hash/AbstractHasher.java | 5 +- .../AbstractNonStreamingHashFunction.java | 14 +- .../common/hash/AbstractStreamingHasher.java | 1 + .../com/google/common/hash/BloomFilter.java | 69 +- .../common/hash/BloomFilterStrategies.java | 83 +- .../common/hash/ChecksumHashFunction.java | 1 + .../common/hash/Crc32cHashFunction.java | 1 + .../hash/ElementTypesAreNonnullByDefault.java | 41 + .../common/hash/FarmHashFingerprint64.java | 3 +- .../google/common/hash/Fingerprint2011.java | 198 +++ guava/src/com/google/common/hash/Funnel.java | 6 +- guava/src/com/google/common/hash/Funnels.java | 16 +- .../src/com/google/common/hash/HashCode.java | 18 +- .../com/google/common/hash/HashFunction.java | 7 +- guava/src/com/google/common/hash/Hasher.java | 5 +- guava/src/com/google/common/hash/Hashing.java | 89 +- .../common/hash/HashingInputStream.java | 12 +- .../common/hash/HashingOutputStream.java | 1 + .../google/common/hash/ImmutableSupplier.java | 2 + .../common/hash/Java8Compatibility.java | 1 + .../common/hash/LittleEndianByteArray.java | 6 +- .../com/google/common/hash/LongAddable.java | 2 + .../com/google/common/hash/LongAddables.java | 4 +- .../src/com/google/common/hash/LongAdder.java | 1 + .../google/common/hash/MacHashFunction.java | 7 +- .../hash/MessageDigestHashFunction.java | 5 +- .../common/hash/Murmur3_128HashFunction.java | 6 +- .../common/hash/Murmur3_32HashFunction.java | 34 +- .../common/hash/ParametricNullness.java | 52 + .../com/google/common/hash/PrimitiveSink.java | 1 + .../google/common/hash/SipHashFunction.java | 4 +- .../src/com/google/common/hash/Striped64.java | 17 +- .../html/ElementTypesAreNonnullByDefault.java | 41 + .../com/google/common/html/HtmlEscapers.java | 1 + .../common/html/ParametricNullness.java | 52 + .../google/common/io/AppendableWriter.java | 12 +- .../com/google/common/io/BaseEncoding.java | 56 +- .../google/common/io/ByteArrayDataInput.java | 3 + .../google/common/io/ByteArrayDataOutput.java | 1 + .../com/google/common/io/ByteProcessor.java | 5 +- guava/src/com/google/common/io/ByteSink.java | 1 + .../src/com/google/common/io/ByteSource.java | 21 +- .../src/com/google/common/io/ByteStreams.java | 45 +- .../google/common/io/CharSequenceReader.java | 29 +- guava/src/com/google/common/io/CharSink.java | 1 + .../src/com/google/common/io/CharSource.java | 25 +- .../src/com/google/common/io/CharStreams.java | 12 +- .../src/com/google/common/io/Closeables.java | 9 +- guava/src/com/google/common/io/Closer.java | 39 +- .../google/common/io/CountingInputStream.java | 1 + .../common/io/CountingOutputStream.java | 1 + .../io/ElementTypesAreNonnullByDefault.java | 41 + .../common/io/FileBackedOutputStream.java | 31 +- .../com/google/common/io/FileWriteMode.java | 1 + guava/src/com/google/common/io/Files.java | 85 +- .../src/com/google/common/io/Flushables.java | 1 + .../io/InsecureRecursiveDeleteException.java | 5 +- .../google/common/io/Java8Compatibility.java | 9 + .../src/com/google/common/io/LineBuffer.java | 15 +- .../com/google/common/io/LineProcessor.java | 5 +- .../src/com/google/common/io/LineReader.java | 8 +- .../io/LittleEndianDataInputStream.java | 3 +- .../io/LittleEndianDataOutputStream.java | 1 + guava/src/com/google/common/io/MoreFiles.java | 96 +- .../google/common/io/MultiInputStream.java | 7 +- .../src/com/google/common/io/MultiReader.java | 9 +- .../google/common/io/ParametricNullness.java | 52 + .../common/io/PatternFilenameFilter.java | 17 +- .../google/common/io/ReaderInputStream.java | 5 +- .../common/io/RecursiveDeleteOption.java | 1 + guava/src/com/google/common/io/Resources.java | 11 +- .../google/common/math/BigDecimalMath.java | 1 + .../google/common/math/BigIntegerMath.java | 11 +- .../com/google/common/math/DoubleMath.java | 3 +- .../com/google/common/math/DoubleUtils.java | 1 + .../math/ElementTypesAreNonnullByDefault.java | 41 + guava/src/com/google/common/math/IntMath.java | 5 +- .../common/math/LinearTransformation.java | 6 +- .../src/com/google/common/math/LongMath.java | 11 +- .../google/common/math/MathPreconditions.java | 16 +- .../com/google/common/math/PairedStats.java | 5 +- .../common/math/PairedStatsAccumulator.java | 1 + .../common/math/ParametricNullness.java | 52 + .../src/com/google/common/math/Quantiles.java | 1 + guava/src/com/google/common/math/Stats.java | 4 +- .../google/common/math/StatsAccumulator.java | 1 + .../google/common/math/ToDoubleRounder.java | 1 + .../net/ElementTypesAreNonnullByDefault.java | 41 + .../com/google/common/net/HostAndPort.java | 22 +- .../com/google/common/net/HostSpecifier.java | 19 +- .../com/google/common/net/HttpHeaders.java | 187 ++- .../com/google/common/net/InetAddresses.java | 73 +- .../google/common/net/InternetDomainName.java | 17 +- .../src/com/google/common/net/MediaType.java | 38 +- .../google/common/net/ParametricNullness.java | 52 + .../com/google/common/net/PercentEscaper.java | 5 +- .../com/google/common/net/UrlEscapers.java | 1 + .../com/google/common/net/package-info.java | 2 + .../google/common/primitives/Booleans.java | 23 +- .../com/google/common/primitives/Bytes.java | 20 +- .../com/google/common/primitives/Chars.java | 20 +- .../com/google/common/primitives/Doubles.java | 23 +- .../primitives/DoublesMethodsForWeb.java | 1 + .../ElementTypesAreNonnullByDefault.java | 41 + .../com/google/common/primitives/Floats.java | 23 +- .../primitives/FloatsMethodsForWeb.java | 1 + .../primitives/ImmutableDoubleArray.java | 23 +- .../common/primitives/ImmutableIntArray.java | 23 +- .../common/primitives/ImmutableLongArray.java | 23 +- .../com/google/common/primitives/Ints.java | 23 +- .../common/primitives/IntsMethodsForWeb.java | 1 + .../com/google/common/primitives/Longs.java | 21 +- .../common/primitives/ParametricNullness.java | 52 + .../common/primitives/ParseRequest.java | 1 + .../google/common/primitives/Platform.java | 1 + .../google/common/primitives/Primitives.java | 1 + .../com/google/common/primitives/Shorts.java | 20 +- .../primitives/ShortsMethodsForWeb.java | 1 + .../google/common/primitives/SignedBytes.java | 1 + .../common/primitives/UnsignedBytes.java | 9 +- .../common/primitives/UnsignedInteger.java | 6 +- .../common/primitives/UnsignedInts.java | 1 + .../common/primitives/UnsignedLong.java | 26 +- .../common/primitives/UnsignedLongs.java | 1 + .../reflect/AbstractInvocationHandler.java | 12 +- .../com/google/common/reflect/ClassPath.java | 67 +- .../com/google/common/reflect/Element.java | 178 --- .../ElementTypesAreNonnullByDefault.java | 41 + .../reflect/ImmutableTypeToInstanceMap.java | 17 +- .../com/google/common/reflect/Invokable.java | 184 ++- .../reflect/MutableTypeToInstanceMap.java | 51 +- .../com/google/common/reflect/Parameter.java | 20 +- .../common/reflect/ParametricNullness.java | 52 + .../com/google/common/reflect/Reflection.java | 3 +- .../google/common/reflect/TypeCapture.java | 1 + .../google/common/reflect/TypeParameter.java | 17 +- .../google/common/reflect/TypeResolver.java | 25 +- .../common/reflect/TypeToInstanceMap.java | 20 +- .../com/google/common/reflect/TypeToken.java | 98 +- .../google/common/reflect/TypeVisitor.java | 4 +- .../src/com/google/common/reflect/Types.java | 61 +- .../concurrent/AbstractCatchingFuture.java | 37 +- .../AbstractExecutionThreadService.java | 1 + .../util/concurrent/AbstractFuture.java | 244 +++- .../util/concurrent/AbstractIdleService.java | 1 + .../AbstractListeningExecutorService.java | 11 +- .../concurrent/AbstractScheduledService.java | 188 ++- .../util/concurrent/AbstractService.java | 15 +- .../concurrent/AbstractTransformFuture.java | 36 +- .../util/concurrent/AggregateFuture.java | 101 +- .../util/concurrent/AggregateFutureState.java | 41 +- .../common/util/concurrent/AsyncCallable.java | 6 +- .../common/util/concurrent/AsyncFunction.java | 5 +- .../common/util/concurrent/AtomicDouble.java | 68 +- .../util/concurrent/AtomicDoubleArray.java | 80 +- .../common/util/concurrent/AtomicLongMap.java | 5 +- .../common/util/concurrent/Atomics.java | 18 +- .../common/util/concurrent/Callables.java | 71 +- .../common/util/concurrent/ClosingFuture.java | 173 ++- .../util/concurrent/CollectionFuture.java | 32 +- .../util/concurrent/CombinedFuture.java | 45 +- .../concurrent/CycleDetectingLockFactory.java | 40 +- .../util/concurrent/DirectExecutor.java | 1 + .../ElementTypesAreNonnullByDefault.java | 41 + .../util/concurrent/ExecutionError.java | 15 +- .../common/util/concurrent/ExecutionList.java | 11 +- .../util/concurrent/ExecutionSequencer.java | 168 ++- .../util/concurrent/FakeTimeLimiter.java | 10 +- .../common/util/concurrent/FluentFuture.java | 25 +- .../concurrent/ForwardingBlockingDeque.java | 5 + .../concurrent/ForwardingBlockingQueue.java | 3 + .../util/concurrent/ForwardingCondition.java | 1 + .../concurrent/ForwardingExecutorService.java | 18 +- .../concurrent/ForwardingFluentFuture.java | 6 +- .../util/concurrent/ForwardingFuture.java | 10 +- .../ForwardingListenableFuture.java | 8 +- .../ForwardingListeningExecutorService.java | 7 +- .../util/concurrent/ForwardingLock.java | 1 + .../util/concurrent/FutureCallback.java | 5 +- .../common/util/concurrent/Futures.java | 215 ++-- .../util/concurrent/FuturesGetChecked.java | 21 +- ...GwtFluentFutureCatchingSpecialization.java | 5 +- .../GwtFuturesCatchingSpecialization.java | 1 + .../util/concurrent/IgnoreJRERequirement.java | 24 - .../util/concurrent/ImmediateFuture.java | 18 +- .../common/util/concurrent/Internal.java | 1 + .../util/concurrent/InterruptibleTask.java | 201 ++- .../util/concurrent/JdkFutureAdapters.java | 43 +- .../util/concurrent/ListenableFuture.java | 19 +- .../util/concurrent/ListenableFutureTask.java | 16 +- .../concurrent/ListenableScheduledFuture.java | 7 +- .../util/concurrent/ListenerCallQueue.java | 3 +- .../concurrent/ListeningExecutorService.java | 11 +- .../ListeningScheduledExecutorService.java | 8 +- .../common/util/concurrent/Monitor.java | 17 +- .../common/util/concurrent/MoreExecutors.java | 85 +- .../common/util/concurrent/NullnessCasts.java | 76 ++ .../OverflowAvoidingLockSupport.java | 5 +- .../util/concurrent/ParametricNullness.java | 52 + .../common/util/concurrent/Partially.java | 1 + .../common/util/concurrent/Platform.java | 5 +- .../common/util/concurrent/RateLimiter.java | 5 +- .../common/util/concurrent/Runnables.java | 1 + .../util/concurrent/SequentialExecutor.java | 10 +- .../common/util/concurrent/Service.java | 46 +- .../util/concurrent/ServiceManager.java | 25 +- .../util/concurrent/ServiceManagerBridge.java | 1 + .../util/concurrent/SettableFuture.java | 10 +- .../util/concurrent/SimpleTimeLimiter.java | 35 +- .../util/concurrent/SmoothRateLimiter.java | 1 + .../common/util/concurrent/Striped.java | 98 +- .../util/concurrent/ThreadFactoryBuilder.java | 34 +- .../common/util/concurrent/TimeLimiter.java | 13 +- .../common/util/concurrent/TimeoutFuture.java | 17 +- .../TrustedListenableFutureTask.java | 54 +- .../concurrent/UncaughtExceptionHandlers.java | 1 + .../UncheckedExecutionException.java | 15 +- .../concurrent/UncheckedTimeoutException.java | 9 +- .../util/concurrent/Uninterruptibles.java | 28 +- .../concurrent/WrappingExecutorService.java | 40 +- .../WrappingScheduledExecutorService.java | 5 +- .../xml/ElementTypesAreNonnullByDefault.java | 41 + .../google/common/xml/ParametricNullness.java | 52 + .../com/google/common/xml/XmlEscapers.java | 3 +- .../publicsuffix/PublicSuffixPatterns.java | 6 +- .../thirdparty/publicsuffix/TrieParser.java | 2 +- pom.xml | 98 +- 1638 files changed, 37236 insertions(+), 18409 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 android/guava-tests/test/com/google/common/eventbus/outside/AbstractEventBusTest.java create mode 100644 android/guava-tests/test/com/google/common/eventbus/outside/AbstractNotAnnotatedInSuperclassTest.java create mode 100644 android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedAndAbstractInSuperclassTest.java create mode 100644 android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedNotAbstractInSuperclassTest.java delete mode 100644 android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedSubscriberFinderTests.java create mode 100644 android/guava-tests/test/com/google/common/eventbus/outside/BaseSubscriberFinderTest.java create mode 100644 android/guava-tests/test/com/google/common/eventbus/outside/DeepInterfaceTest.java create mode 100644 android/guava-tests/test/com/google/common/eventbus/outside/NeitherAbstractNorAnnotatedInSuperclassTest.java create mode 100644 android/guava-tests/test/com/google/common/hash/Fingerprint2011Test.java delete mode 100644 android/guava-tests/test/com/google/common/reflect/ElementTest.java rename android/guava-tests/test/com/google/common/util/concurrent/{ClosingFutureTest.java => AbstractClosingFutureTest.java} (91%) create mode 100644 android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureFinishToFutureTest.java create mode 100644 android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureFinishToValueAndCloserTest.java create mode 100644 android/guava/src/com/google/common/base/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/base/Java8Compatibility.java delete mode 100755 android/guava/src/com/google/common/base/Java8Usage.java create mode 100644 android/guava/src/com/google/common/base/NullnessCasts.java create mode 100644 android/guava/src/com/google/common/base/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/cache/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/cache/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/collect/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/collect/NullnessCasts.java create mode 100644 android/guava/src/com/google/common/collect/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/escape/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/escape/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/eventbus/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/eventbus/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/graph/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/graph/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/hash/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/hash/Fingerprint2011.java create mode 100644 android/guava/src/com/google/common/hash/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/html/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/html/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/io/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/io/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/math/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/math/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/net/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/net/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/primitives/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/primitives/ParametricNullness.java delete mode 100644 android/guava/src/com/google/common/reflect/Element.java create mode 100644 android/guava/src/com/google/common/reflect/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/reflect/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/util/concurrent/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/util/concurrent/NullnessCasts.java create mode 100644 android/guava/src/com/google/common/util/concurrent/ParametricNullness.java create mode 100644 android/guava/src/com/google/common/xml/ElementTypesAreNonnullByDefault.java create mode 100644 android/guava/src/com/google/common/xml/ParametricNullness.java create mode 100644 guava-tests/test/com/google/common/base/StopwatchJavaTimeTest.java create mode 100644 guava-tests/test/com/google/common/collect/CompactHashMapFloodingTest.java create mode 100644 guava-tests/test/com/google/common/collect/CompactHashSetFloodingTest.java rename android/guava/src/com/google/common/util/concurrent/IgnoreJRERequirement.java => guava-tests/test/com/google/common/collect/CompactLinkedHashMapFloodingTest.java (56%) create mode 100644 guava-tests/test/com/google/common/collect/CompactLinkedHashSetFloodingTest.java create mode 100644 guava-tests/test/com/google/common/eventbus/outside/AbstractEventBusTest.java create mode 100644 guava-tests/test/com/google/common/eventbus/outside/AbstractNotAnnotatedInSuperclassTest.java create mode 100644 guava-tests/test/com/google/common/eventbus/outside/AnnotatedAndAbstractInSuperclassTest.java create mode 100644 guava-tests/test/com/google/common/eventbus/outside/AnnotatedNotAbstractInSuperclassTest.java delete mode 100644 guava-tests/test/com/google/common/eventbus/outside/AnnotatedSubscriberFinderTests.java create mode 100644 guava-tests/test/com/google/common/eventbus/outside/BaseSubscriberFinderTest.java create mode 100644 guava-tests/test/com/google/common/eventbus/outside/DeepInterfaceTest.java create mode 100644 guava-tests/test/com/google/common/eventbus/outside/NeitherAbstractNorAnnotatedInSuperclassTest.java create mode 100644 guava-tests/test/com/google/common/hash/Fingerprint2011Test.java delete mode 100644 guava-tests/test/com/google/common/reflect/ElementTest.java rename guava-tests/test/com/google/common/util/concurrent/{ClosingFutureTest.java => AbstractClosingFutureTest.java} (91%) create mode 100644 guava-tests/test/com/google/common/util/concurrent/ClosingFutureFinishToFutureTest.java create mode 100644 guava-tests/test/com/google/common/util/concurrent/ClosingFutureFinishToValueAndCloserTest.java create mode 100644 guava/src/com/google/common/base/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/base/Java8Compatibility.java delete mode 100644 guava/src/com/google/common/base/Java8Usage.java create mode 100644 guava/src/com/google/common/base/NullnessCasts.java create mode 100644 guava/src/com/google/common/base/ParametricNullness.java create mode 100644 guava/src/com/google/common/cache/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/cache/ParametricNullness.java create mode 100644 guava/src/com/google/common/collect/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/collect/NullnessCasts.java create mode 100644 guava/src/com/google/common/collect/ParametricNullness.java create mode 100644 guava/src/com/google/common/escape/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/escape/ParametricNullness.java create mode 100644 guava/src/com/google/common/eventbus/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/eventbus/ParametricNullness.java create mode 100644 guava/src/com/google/common/graph/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/graph/ParametricNullness.java create mode 100644 guava/src/com/google/common/hash/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/hash/Fingerprint2011.java create mode 100644 guava/src/com/google/common/hash/ParametricNullness.java create mode 100644 guava/src/com/google/common/html/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/html/ParametricNullness.java create mode 100644 guava/src/com/google/common/io/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/io/ParametricNullness.java create mode 100644 guava/src/com/google/common/math/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/math/ParametricNullness.java create mode 100644 guava/src/com/google/common/net/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/net/ParametricNullness.java create mode 100644 guava/src/com/google/common/primitives/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/primitives/ParametricNullness.java delete mode 100644 guava/src/com/google/common/reflect/Element.java create mode 100644 guava/src/com/google/common/reflect/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/reflect/ParametricNullness.java create mode 100644 guava/src/com/google/common/util/concurrent/ElementTypesAreNonnullByDefault.java delete mode 100644 guava/src/com/google/common/util/concurrent/IgnoreJRERequirement.java create mode 100644 guava/src/com/google/common/util/concurrent/NullnessCasts.java create mode 100644 guava/src/com/google/common/util/concurrent/ParametricNullness.java create mode 100644 guava/src/com/google/common/xml/ElementTypesAreNonnullByDefault.java create mode 100644 guava/src/com/google/common/xml/ParametricNullness.java diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000000..1e956d2faa00 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,16 @@ +version: 2 +updates: +# TODO(b/170636568): Enable Maven updates? Perhaps wait until we can more +# easily import the generated PRs into our internal repo. +# - package-ecosystem: "maven" +# directory: "/" +# schedule: +# interval: "daily" +# - package-ecosystem: "maven" +# directory: "/android" +# schedule: +# interval: "daily" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3e07268881d..e0907fc21b4e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,28 +13,34 @@ jobs: name: "${{ matrix.root-pom }} on JDK ${{ matrix.java }}" strategy: matrix: - java: [ 8, 11 ] + java: [ 11, 17 ] root-pom: [ 'pom.xml', 'android/pom.xml' ] runs-on: ubuntu-latest env: ROOT_POM: ${{ matrix.root-pom }} steps: + # Cancel any previous runs for the same branch that are still running. + - name: 'Cancel previous runs' + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} - name: 'Check out repository' - uses: actions/checkout@v2 + uses: actions/checkout@v2.4.0 - name: 'Cache local Maven repository' - uses: actions/cache@v2.1.4 + uses: actions/cache@v2.1.7 with: path: ~/.m2/repository key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: | maven- - name: 'Set up JDK ${{ matrix.java }}' - uses: actions/setup-java@v1 + uses: actions/setup-java@v2 with: java-version: ${{ matrix.java }} + distribution: 'zulu' - name: 'Install' shell: bash - run: mvn -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install -U -DskipTests=true -f $ROOT_POM + run: mvn -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install -U -Dmaven.test.skip -Dmaven.javadoc.skip -f $ROOT_POM - name: 'Test' shell: bash run: MAVEN_OPTS=-Xmx6g mvn -B -P!standard-with-extra-repos verify -U -Dmaven.javadoc.skip=true -f $ROOT_POM @@ -51,18 +57,19 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Check out repository' - uses: actions/checkout@v2 + uses: actions/checkout@v2.4.0 - name: 'Cache local Maven repository' - uses: actions/cache@v2.1.4 + uses: actions/cache@v2.1.7 with: path: ~/.m2/repository key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: | maven- - name: 'Set up JDK 11' - uses: actions/setup-java@v1 + uses: actions/setup-java@v2 with: java-version: 11 + distribution: 'zulu' server-id: sonatype-nexus-snapshots server-username: CI_DEPLOY_USERNAME server-password: CI_DEPLOY_PASSWORD @@ -79,18 +86,19 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Check out repository' - uses: actions/checkout@v2 + uses: actions/checkout@v2.4.0 - name: 'Cache local Maven repository' - uses: actions/cache@v2.1.4 + uses: actions/cache@v2.1.7 with: path: ~/.m2/repository key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: | maven- - name: 'Set up JDK 11' - uses: actions/setup-java@v1 + uses: actions/setup-java@v2 with: java-version: 11 + distribution: 'zulu' - name: 'Generate latest docs' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README-typetools.md b/README-typetools.md index f552fdfd2b47..686bc55b429b 100644 --- a/README-typetools.md +++ b/README-typetools.md @@ -17,6 +17,27 @@ To use a locally-built Checker Framework, add `-P checkerframework-local`, or change `guava/pom.xml`. +To run the Guava test suite +--------------------------- + +This not strictly necessary as the CI process will run them. But if you wish to do so, +it is a two step process. This can take a long time: 20-30 minutes for the compile step +and 30-35 minutes for the test step. In order to shorten it a bit, the command lines +below only run a single format checker. First, you must run maven with the install +target to get a copy of all the generated jar files in your local maven repository: + +mvn -V -B -U clean install -Dcheckerframework.checkers=org.checkerframework.checker.formatter.FormatterChecker \ + -Dcheck.value.phase=skip -Dmaven.test.skip -Dmaven.javadoc.skip + +Then you run the test suite: + +MAVEN_OPTS=-Xmx6g mvn -V -B -U verify -Dcheckerframework.checkers=org.checkerframework.checker.formatter.FormatterChecker \ + -Dcheck.value.phase=skip -Dmaven.javadoc.skip + +Running with the single FormatterChecker gets the total time down to about 20-25 minutes, +almost all testing. (Over 850,000 tests are run.) + + Typechecking ------------ @@ -148,7 +169,7 @@ yet written. 2. Pull in the latest Guava version (https://github.com/google/guava/releases): ``` git fetch --tags https://github.com/google/guava -git pull https://github.com/google/guava v30.1.1 +git pull https://github.com/google/guava v31.1 ``` 3. Ensure that the project still builds: diff --git a/README.md b/README.md index 67b5a937d05a..8afda8fbb9e0 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,11 @@ utilities for concurrency, I/O, hashing, caching, primitives, strings, and more! is widely used on most Java projects within Google, and widely used by many other companies as well. -Guava comes in two flavors. +Guava comes in two flavors: * The JRE flavor requires JDK 1.8 or higher. -* If you need support for JDK 1.7 or Android, use the Android flavor. You can - find the Android Guava source in the [`android` directory]. +* If you need support for Android, use the Android flavor. You can find the + Android Guava source in the [`android` directory]. [`android` directory]: https://github.com/google/guava/tree/master/android @@ -21,9 +21,9 @@ Guava comes in two flavors. Guava's Maven group ID is `com.google.guava`, and its artifact ID is `guava`. Guava provides two different "flavors": one for use on a (Java 8+) JRE and one -for use on Android or Java 7 or by any library that wants to be compatible with -either of those. These flavors are specified in the Maven version field as -either `30.1-jre` or `30.1-android`. For more about depending on Guava, see +for use on Android or by any library that wants to be compatible with Android. +These flavors are specified in the Maven version field as either `31.1-jre` or +`31.1-android`. For more about depending on Guava, see [using Guava in your build]. To add a dependency on Guava using Maven, use the following: @@ -32,9 +32,9 @@ To add a dependency on Guava using Maven, use the following: com.google.guava guava - 30.1-jre + 31.1-jre - 30.1-android + 31.1-android ``` @@ -45,16 +45,16 @@ dependencies { // Pick one: // 1. Use Guava in your implementation only: - implementation("com.google.guava:guava:30.1-jre") + implementation("com.google.guava:guava:31.1-jre") // 2. Use Guava types in your public API: - api("com.google.guava:guava:30.1-jre") + api("com.google.guava:guava:31.1-jre") // 3. Android - Use Guava in your implementation only: - implementation("com.google.guava:guava:30.1-android") + implementation("com.google.guava:guava:31.1-android") // 4. Android - Use Guava types in your public API: - api("com.google.guava:guava:30.1-android") + api("com.google.guava:guava:31.1-android") } ``` @@ -101,8 +101,10 @@ flavor. plans to start removing things again, but officially, we're leaving our options open in case of surprises (like, say, a serious security problem). -3. Guava has one dependency that is needed at runtime: - `com.google.guava:failureaccess:1.0.1` +3. Guava has one dependency that is needed for linkage at runtime: + `com.google.guava:failureaccess:1.0.1`. It also has + [some annotation-only dependencies][guava-deps], which we discuss in more + detail at that link. 4. Serialized forms of ALL objects are subject to change unless noted otherwise. Do not persist these and assume they can be read by a future @@ -111,10 +113,10 @@ flavor. 5. Our classes are not designed to protect against a malicious caller. You should not use them for communication between trusted and untrusted code. -6. For the mainline flavor, we unit-test the libraries using only OpenJDK 1.8 - on Linux. Some features, especially in `com.google.common.io`, may not work - correctly in other environments. For the Android flavor, our unit tests run - on API level 15 (Ice Cream Sandwich). +6. For the mainline flavor, we test the libraries using only OpenJDK 8 and + OpenJDK 11 on Linux. Some features, especially in `com.google.common.io`, + may not work correctly in other environments. For the Android flavor, our + unit tests also run on API level 15 (Ice Cream Sandwich). [guava-snapshot-api-docs]: https://guava.dev/releases/snapshot-jre/api/docs/ [guava-snapshot-api-diffs]: https://guava.dev/releases/snapshot-jre/api/diffs/ @@ -125,3 +127,4 @@ flavor. [using Guava in your build]: https://github.com/google/guava/wiki/UseGuavaInYourBuild [repackage]: https://github.com/google/guava/wiki/UseGuavaInYourBuild#what-if-i-want-to-use-beta-apis-from-a-library-that-people-use-as-a-dependency +[guava-deps]: https://github.com/google/guava/wiki/UseGuavaInYourBuild#what-about-guavas-own-dependencies diff --git a/android/guava-bom/pom.xml b/android/guava-bom/pom.xml index 8fde93d1a75a..736c02fd8044 100644 --- a/android/guava-bom/pom.xml +++ b/android/guava-bom/pom.xml @@ -8,7 +8,7 @@ com.google.guava guava-bom - HEAD-android-SNAPSHOT + 31.1-android pom diff --git a/android/guava-testlib/pom.xml b/android/guava-testlib/pom.xml index 79b05190ce85..1fcf058676ee 100644 --- a/android/guava-testlib/pom.xml +++ b/android/guava-testlib/pom.xml @@ -5,7 +5,7 @@ com.google.guava guava-parent - HEAD-android-SNAPSHOT + 31.1-android guava-testlib Guava Testing Library @@ -18,10 +18,6 @@ com.google.code.findbugs jsr305 - - org.checkerframework - checker-compat-qual - com.google.errorprone error_prone_annotations diff --git a/android/guava-testlib/src/com/google/common/collect/testing/AbstractContainerTester.java b/android/guava-testlib/src/com/google/common/collect/testing/AbstractContainerTester.java index a5674d3db4d0..b86ef1750dee 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/AbstractContainerTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/AbstractContainerTester.java @@ -188,7 +188,7 @@ protected ArrayWithDuplicate createArrayWithDuplicateElement() { E[] elements = createSamplesArray(); E duplicate = elements[(elements.length / 2) - 1]; elements[(elements.length / 2) + 1] = duplicate; - return new ArrayWithDuplicate(elements, duplicate); + return new ArrayWithDuplicate<>(elements, duplicate); } // Helper methods to improve readability of derived classes @@ -211,7 +211,7 @@ protected Collection getSampleElements() { * requirement {@link com.google.common.collect.testing.features.CollectionFeature#KNOWN_ORDER}. */ protected List getOrderedElements() { - List list = new ArrayList(); + List list = new ArrayList<>(); for (E e : getSubjectGenerator().order(new ArrayList(getSampleElements()))) { list.add(e); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/AbstractMapTester.java b/android/guava-testlib/src/com/google/common/collect/testing/AbstractMapTester.java index 090442edc4da..5e0de3ccc443 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/AbstractMapTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/AbstractMapTester.java @@ -72,8 +72,8 @@ protected void expectMissingValues(V... elements) { /** @return an array of the proper size with {@code null} as the key of the middle element. */ protected Entry[] createArrayWithNullKey() { Entry[] array = createSamplesArray(); - final int nullKeyLocation = getNullLocation(); - final Entry oldEntry = array[nullKeyLocation]; + int nullKeyLocation = getNullLocation(); + Entry oldEntry = array[nullKeyLocation]; array[nullKeyLocation] = entry(null, oldEntry.getValue()); return array; } @@ -97,8 +97,8 @@ private Entry getEntryNullReplaces() { /** @return an array of the proper size with {@code null} as the value of the middle element. */ protected Entry[] createArrayWithNullValue() { Entry[] array = createSamplesArray(); - final int nullValueLocation = getNullLocation(); - final Entry oldEntry = array[nullValueLocation]; + int nullValueLocation = getNullLocation(); + Entry oldEntry = array[nullValueLocation]; array[nullValueLocation] = entry(oldEntry.getKey(), null); return array; } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java index cf1ed23aa41e..5f9aff4f1c5f 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java @@ -57,6 +57,8 @@ protected List createDerivedSuites( .named(getName() + " reserialized") .withFeatures(computeReserializedCollectionFeatures(parentBuilder.getFeatures())) .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); } return derivedSuites; diff --git a/android/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java b/android/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java index 3588e856fa23..a04d3ffe300a 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java @@ -96,9 +96,9 @@ public static class MapKeySetGenerator implements TestSetGenerator, Der public MapKeySetGenerator(OneSizeTestContainerGenerator, Entry> mapGenerator) { this.mapGenerator = mapGenerator; - final SampleElements> mapSamples = this.mapGenerator.samples(); + SampleElements> mapSamples = this.mapGenerator.samples(); this.samples = - new SampleElements( + new SampleElements<>( mapSamples.e0().getKey(), mapSamples.e1().getKey(), mapSamples.e2().getKey(), @@ -203,9 +203,9 @@ public static class MapValueCollectionGenerator public MapValueCollectionGenerator( OneSizeTestContainerGenerator, Entry> mapGenerator) { this.mapGenerator = mapGenerator; - final SampleElements> mapSamples = this.mapGenerator.samples(); + SampleElements> mapSamples = this.mapGenerator.samples(); this.samples = - new SampleElements( + new SampleElements<>( mapSamples.e0().getValue(), mapSamples.e1().getValue(), mapSamples.e2().getValue(), @@ -239,14 +239,13 @@ public Collection create(Object... elements) { @Override public V[] createArray(int length) { // noinspection UnnecessaryLocalVariable - final V[] vs = - ((TestMapGenerator) mapGenerator.getInnerGenerator()).createValueArray(length); + V[] vs = ((TestMapGenerator) mapGenerator.getInnerGenerator()).createValueArray(length); return vs; } @Override public Iterable order(List insertionOrder) { - final List> orderedEntries = + List> orderedEntries = castOrCopyToList(mapGenerator.order(castOrCopyToList(mapGenerator.getSampleElements(5)))); sort( insertionOrder, diff --git a/android/guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java index 0d921a580896..db086aa3075e 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java @@ -81,7 +81,7 @@ public B withSetUp(Runnable setUp) { return self(); } - protected Runnable getSetUp() { + public Runnable getSetUp() { return setUp; } @@ -90,13 +90,13 @@ public B withTearDown(Runnable tearDown) { return self(); } - protected Runnable getTearDown() { + public Runnable getTearDown() { return tearDown; } // Features - private Set> features = new LinkedHashSet<>(); + private final Set> features = new LinkedHashSet<>(); /** * Configures this builder to produce tests appropriate for the given features. This method may be @@ -138,7 +138,7 @@ public String getName() { // Test suppression - private Set suppressedTests = new HashSet<>(); + private final Set suppressedTests = new HashSet<>(); /** * Prevents the given methods from being run as part of the test suite. @@ -185,7 +185,7 @@ public TestSuite createTestSuite() { TestSuite suite = new TestSuite(name); for (Class testerClass : testers) { - final TestSuite testerSuite = + TestSuite testerSuite = makeSuiteForTesterClass((Class>) testerClass); if (testerSuite.countTestCases() > 0) { suite.addTest(testerSuite); @@ -211,7 +211,7 @@ protected void checkCanCreate() { protected abstract List> getTesters(); private boolean matches(Test test) { - final Method method; + Method method; try { method = extractMethod(test); } catch (IllegalArgumentException e) { @@ -222,7 +222,7 @@ private boolean matches(Test test) { logger.finer(Platform.format("%s: excluding because it was explicitly suppressed.", test)); return false; } - final TesterRequirements requirements; + TesterRequirements requirements; try { requirements = FeatureUtil.getTesterRequirements(method); } catch (ConflictingRequirementsException e) { @@ -268,8 +268,8 @@ private static Method extractMethod(Test test) { } protected TestSuite makeSuiteForTesterClass(Class> testerClass) { - final TestSuite candidateTests = new TestSuite(testerClass); - final TestSuite suite = filterSuite(candidateTests); + TestSuite candidateTests = new TestSuite(testerClass); + TestSuite suite = filterSuite(candidateTests); Enumeration allTests = suite.tests(); while (allTests.hasMoreElements()) { @@ -286,7 +286,7 @@ protected TestSuite makeSuiteForTesterClass(Class> t private TestSuite filterSuite(TestSuite suite) { TestSuite filtered = new TestSuite(suite.getName()); - final Enumeration tests = suite.tests(); + Enumeration tests = suite.tests(); while (tests.hasMoreElements()) { Test test = (Test) tests.nextElement(); if (matches(test)) { diff --git a/android/guava-testlib/src/com/google/common/collect/testing/Helpers.java b/android/guava-testlib/src/com/google/common/collect/testing/Helpers.java index 8efafc373525..aac71cc4efe3 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/Helpers.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/Helpers.java @@ -49,7 +49,7 @@ static boolean equal(Object a, Object b) { // Clone of Lists.newArrayList public static List copyToList(Iterable elements) { - List list = new ArrayList(); + List list = new ArrayList<>(); addAll(list, elements); return list; } @@ -60,7 +60,7 @@ public static List copyToList(E[] elements) { // Clone of Sets.newLinkedHashSet public static Set copyToSet(Iterable elements) { - Set set = new LinkedHashSet(); + Set set = new LinkedHashSet<>(); addAll(set, elements); return set; } @@ -188,11 +188,11 @@ public static boolean addAll(Collection addTo, Iterable elem return modified; } - static Iterable reverse(final List list) { + static Iterable reverse(List list) { return new Iterable() { @Override public Iterator iterator() { - final ListIterator listIter = list.listIterator(list.size()); + ListIterator listIter = list.listIterator(list.size()); return new Iterator() { @Override public boolean hasNext() { @@ -213,7 +213,7 @@ public void remove() { }; } - static Iterator cycle(final Iterable iterable) { + static Iterator cycle(Iterable iterable) { return new Iterator() { Iterator iterator = Collections.emptySet().iterator(); @@ -251,7 +251,7 @@ static void fail(Throwable cause, Object message) { } public static Comparator> entryComparator( - final Comparator keyComparator) { + Comparator keyComparator) { return new Comparator>() { @Override @SuppressWarnings("unchecked") // no less safe than putting it in the map! @@ -345,7 +345,7 @@ public static > void testCompareToAndEquals( * @param delta the difference between the true size of the collection and the values returned by * the size method */ - public static Collection misleadingSizeCollection(final int delta) { + public static Collection misleadingSizeCollection(int delta) { // It would be nice to be able to return a real concurrent // collection like ConcurrentLinkedQueue, so that e.g. concurrent // iteration would work, but that would not be GWT-compatible. @@ -363,7 +363,7 @@ public int size() { * equals. This is used for testing unmodifiable collections of map entries; for example, it * should not be possible to access the raw (modifiable) map entry via a nefarious equals method. */ - public static Entry nefariousMapEntry(final K key, final V value) { + public static Entry nefariousMapEntry(K key, V value) { return new Entry() { @Override public K getKey() { @@ -410,7 +410,7 @@ static List castOrCopyToList(Iterable iterable) { if (iterable instanceof List) { return (List) iterable; } - List list = new ArrayList(); + List list = new ArrayList<>(); for (E e : iterable) { list.add(e); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java index e01056459338..061e31038bda 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java @@ -112,6 +112,8 @@ protected List createDerivedSuites( .named(getName() + " reserialized") .withFeatures(computeReserializedCollectionFeatures(parentBuilder.getFeatures())) .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); } return derivedSuites; diff --git a/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java b/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java index b8b5c28fb936..48491387851f 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java @@ -149,7 +149,7 @@ protected final boolean supportsValuesHashCode(Map map) { for (V value : values) { if (value != null) { try { - value.hashCode(); + int unused = value.hashCode(); } catch (Exception e) { return false; } @@ -265,7 +265,7 @@ private void assertEntrySetNotContainsString(Set> entrySet) { protected void assertMoreInvariants(Map map) {} public void testClear() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -286,8 +286,8 @@ public void testClear() { } public void testContainsKey() { - final Map map; - final K unmappedKey; + Map map; + K unmappedKey; try { map = makePopulatedMap(); unmappedKey = getKeyNotInPopulatedMap(); @@ -312,8 +312,8 @@ public void testContainsKey() { } public void testContainsValue() { - final Map map; - final V unmappedValue; + Map map; + V unmappedValue; try { map = makePopulatedMap(); unmappedValue = getValueNotInPopulatedMap(); @@ -334,8 +334,8 @@ public void testContainsValue() { } public void testEntrySet() { - final Map map; - final Set> entrySet; + Map map; + Set> entrySet; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -344,8 +344,8 @@ public void testEntrySet() { assertInvariants(map); entrySet = map.entrySet(); - final K unmappedKey; - final V unmappedValue; + K unmappedKey; + V unmappedValue; try { unmappedKey = getKeyNotInPopulatedMap(); unmappedValue = getValueNotInPopulatedMap(); @@ -359,7 +359,7 @@ public void testEntrySet() { } public void testEntrySetForEmptyMap() { - final Map map; + Map map; try { map = makeEmptyMap(); } catch (UnsupportedOperationException e) { @@ -369,8 +369,8 @@ public void testEntrySetForEmptyMap() { } public void testEntrySetContainsEntryIncompatibleKey() { - final Map map; - final Set> entrySet; + Map map; + Set> entrySet; try { map = makeEitherMap(); } catch (UnsupportedOperationException e) { @@ -379,7 +379,7 @@ public void testEntrySetContainsEntryIncompatibleKey() { assertInvariants(map); entrySet = map.entrySet(); - final V unmappedValue; + V unmappedValue; try { unmappedValue = getValueNotInPopulatedMap(); } catch (UnsupportedOperationException e) { @@ -396,8 +396,8 @@ public void testEntrySetContainsEntryNullKeyPresent() { if (!allowsNullKeys || !supportsPut) { return; } - final Map map; - final Set> entrySet; + Map map; + Set> entrySet; try { map = makeEitherMap(); } catch (UnsupportedOperationException e) { @@ -406,7 +406,7 @@ public void testEntrySetContainsEntryNullKeyPresent() { assertInvariants(map); entrySet = map.entrySet(); - final V unmappedValue; + V unmappedValue; try { unmappedValue = getValueNotInPopulatedMap(); } catch (UnsupportedOperationException e) { @@ -420,8 +420,8 @@ public void testEntrySetContainsEntryNullKeyPresent() { } public void testEntrySetContainsEntryNullKeyMissing() { - final Map map; - final Set> entrySet; + Map map; + Set> entrySet; try { map = makeEitherMap(); } catch (UnsupportedOperationException e) { @@ -430,7 +430,7 @@ public void testEntrySetContainsEntryNullKeyMissing() { assertInvariants(map); entrySet = map.entrySet(); - final V unmappedValue; + V unmappedValue; try { unmappedValue = getValueNotInPopulatedMap(); } catch (UnsupportedOperationException e) { @@ -450,7 +450,7 @@ public void testEntrySetContainsEntryNullKeyMissing() { } public void testEntrySetIteratorRemove() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -488,7 +488,7 @@ public void testEntrySetIteratorRemove() { } public void testEntrySetRemove() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -512,8 +512,8 @@ public void testEntrySetRemove() { } public void testEntrySetRemoveMissingKey() { - final Map map; - final K key; + Map map; + K key; try { map = makeEitherMap(); key = getKeyNotInPopulatedMap(); @@ -540,7 +540,7 @@ public void testEntrySetRemoveMissingKey() { } public void testEntrySetRemoveDifferentValue() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -570,8 +570,8 @@ public void testEntrySetRemoveNullKeyPresent() { if (!allowsNullKeys || !supportsPut || !supportsRemove) { return; } - final Map map; - final Set> entrySet; + Map map; + Set> entrySet; try { map = makeEitherMap(); } catch (UnsupportedOperationException e) { @@ -580,7 +580,7 @@ public void testEntrySetRemoveNullKeyPresent() { assertInvariants(map); entrySet = map.entrySet(); - final V unmappedValue; + V unmappedValue; try { unmappedValue = getValueNotInPopulatedMap(); } catch (UnsupportedOperationException e) { @@ -597,7 +597,7 @@ public void testEntrySetRemoveNullKeyPresent() { } public void testEntrySetRemoveNullKeyMissing() { - final Map map; + Map map; try { map = makeEitherMap(); } catch (UnsupportedOperationException e) { @@ -626,7 +626,7 @@ public void testEntrySetRemoveNullKeyMissing() { } public void testEntrySetRemoveAll() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -663,7 +663,7 @@ public void testEntrySetRemoveAll() { } public void testEntrySetRemoveAllNullFromEmpty() { - final Map map; + Map map; try { map = makeEmptyMap(); } catch (UnsupportedOperationException e) { @@ -689,7 +689,7 @@ public void testEntrySetRemoveAllNullFromEmpty() { } public void testEntrySetRetainAll() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -717,7 +717,7 @@ public void testEntrySetRetainAll() { } public void testEntrySetRetainAllNullFromEmpty() { - final Map map; + Map map; try { map = makeEmptyMap(); } catch (UnsupportedOperationException e) { @@ -743,7 +743,7 @@ public void testEntrySetRetainAllNullFromEmpty() { } public void testEntrySetClear() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -765,10 +765,10 @@ public void testEntrySetClear() { } public void testEntrySetAddAndAddAll() { - final Map map = makeEitherMap(); + Map map = makeEitherMap(); Set> entrySet = map.entrySet(); - final Entry entryToAdd = mapEntry(null, null); + Entry entryToAdd = mapEntry(null, null); try { entrySet.add(entryToAdd); fail("Expected UnsupportedOperationException or NullPointerException."); @@ -793,8 +793,8 @@ public void testEntrySetSetValue() { return; } - final Map map; - final V valueToSet; + Map map; + V valueToSet; try { map = makePopulatedMap(); valueToSet = getValueNotInPopulatedMap(); @@ -804,8 +804,8 @@ public void testEntrySetSetValue() { Set> entrySet = map.entrySet(); Entry entry = entrySet.iterator().next(); - final V oldValue = entry.getValue(); - final V returnedValue = entry.setValue(valueToSet); + V oldValue = entry.getValue(); + V returnedValue = entry.setValue(valueToSet); assertEquals(oldValue, returnedValue); assertTrue(entrySet.contains(mapEntry(entry.getKey(), valueToSet))); assertEquals(valueToSet, map.get(entry.getKey())); @@ -819,7 +819,7 @@ public void testEntrySetSetValueSameValue() { return; } - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -828,8 +828,8 @@ public void testEntrySetSetValueSameValue() { Set> entrySet = map.entrySet(); Entry entry = entrySet.iterator().next(); - final V oldValue = entry.getValue(); - final V returnedValue = entry.setValue(oldValue); + V oldValue = entry.getValue(); + V returnedValue = entry.setValue(oldValue); assertEquals(oldValue, returnedValue); assertTrue(entrySet.contains(mapEntry(entry.getKey(), oldValue))); assertEquals(oldValue, map.get(entry.getKey())); @@ -837,15 +837,16 @@ public void testEntrySetSetValueSameValue() { } public void testEqualsForEqualMap() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { return; } - assertEquals(map, map); - assertEquals(makePopulatedMap(), map); + // Explicitly call `equals`; `assertEquals` might return fast + assertTrue(map.equals(map)); + assertTrue(makePopulatedMap().equals(map)); assertFalse(map.equals(Collections.emptyMap())); // no-inspection ObjectEqualsNull assertFalse(map.equals(null)); @@ -856,8 +857,8 @@ public void testEqualsForLargerMap() { return; } - final Map map; - final Map largerMap; + Map map; + Map largerMap; try { map = makePopulatedMap(); largerMap = makePopulatedMap(); @@ -874,8 +875,8 @@ public void testEqualsForSmallerMap() { return; } - final Map map; - final Map smallerMap; + Map map; + Map smallerMap; try { map = makePopulatedMap(); smallerMap = makePopulatedMap(); @@ -888,15 +889,16 @@ public void testEqualsForSmallerMap() { } public void testEqualsForEmptyMap() { - final Map map; + Map map; try { map = makeEmptyMap(); } catch (UnsupportedOperationException e) { return; } - assertEquals(map, map); - assertEquals(makeEmptyMap(), map); + // Explicitly call `equals`; `assertEquals` might return fast + assertTrue(map.equals(map)); + assertTrue(makeEmptyMap().equals(map)); assertEquals(Collections.emptyMap(), map); assertFalse(map.equals(Collections.emptySet())); // noinspection ObjectEqualsNull @@ -904,7 +906,7 @@ public void testEqualsForEmptyMap() { } public void testGet() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -925,7 +927,7 @@ public void testGet() { } public void testGetForEmptyMap() { - final Map map; + Map map; K unmappedKey = null; try { map = makeEmptyMap(); @@ -954,7 +956,7 @@ public void testGetNull() { } public void testHashCode() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -964,7 +966,7 @@ public void testHashCode() { } public void testHashCodeForEmptyMap() { - final Map map; + Map map; try { map = makeEmptyMap(); } catch (UnsupportedOperationException e) { @@ -974,9 +976,9 @@ public void testHashCodeForEmptyMap() { } public void testPutNewKey() { - final Map map = makeEitherMap(); - final K keyToPut; - final V valueToPut; + Map map = makeEitherMap(); + K keyToPut; + V valueToPut; try { keyToPut = getKeyNotInPopulatedMap(); valueToPut = getValueNotInPopulatedMap(); @@ -1002,9 +1004,9 @@ public void testPutNewKey() { } public void testPutExistingKey() { - final Map map; - final K keyToPut; - final V valueToPut; + Map map; + K keyToPut; + V valueToPut; try { map = makePopulatedMap(); valueToPut = getValueNotInPopulatedMap(); @@ -1033,16 +1035,16 @@ public void testPutNullKey() { if (!supportsPut) { return; } - final Map map = makeEitherMap(); - final V valueToPut; + Map map = makeEitherMap(); + V valueToPut; try { valueToPut = getValueNotInPopulatedMap(); } catch (UnsupportedOperationException e) { return; } if (allowsNullKeys) { - final V oldValue = map.get(null); - final V returnedValue = map.put(null, valueToPut); + V oldValue = map.get(null); + V returnedValue = map.put(null, valueToPut); assertEquals(oldValue, returnedValue); assertEquals(valueToPut, map.get(null)); assertTrue(map.containsKey(null)); @@ -1061,8 +1063,8 @@ public void testPutNullValue() { if (!supportsPut) { return; } - final Map map = makeEitherMap(); - final K keyToPut; + Map map = makeEitherMap(); + K keyToPut; try { keyToPut = getKeyNotInPopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1070,8 +1072,8 @@ public void testPutNullValue() { } if (allowsNullValues) { int initialSize = map.size(); - final V oldValue = map.get(keyToPut); - final V returnedValue = map.put(keyToPut, null); + V oldValue = map.get(keyToPut); + V returnedValue = map.put(keyToPut, null); assertEquals(oldValue, returnedValue); assertNull(map.get(keyToPut)); assertTrue(map.containsKey(keyToPut)); @@ -1091,8 +1093,8 @@ public void testPutNullValueForExistingKey() { if (!supportsPut) { return; } - final Map map; - final K keyToPut; + Map map; + K keyToPut; try { map = makePopulatedMap(); keyToPut = map.keySet().iterator().next(); @@ -1101,8 +1103,8 @@ public void testPutNullValueForExistingKey() { } if (allowsNullValues) { int initialSize = map.size(); - final V oldValue = map.get(keyToPut); - final V returnedValue = map.put(keyToPut, null); + V oldValue = map.get(keyToPut); + V returnedValue = map.put(keyToPut, null); assertEquals(oldValue, returnedValue); assertNull(map.get(keyToPut)); assertTrue(map.containsKey(keyToPut)); @@ -1119,16 +1121,16 @@ public void testPutNullValueForExistingKey() { } public void testPutAllNewKey() { - final Map map = makeEitherMap(); - final K keyToPut; - final V valueToPut; + Map map = makeEitherMap(); + K keyToPut; + V valueToPut; try { keyToPut = getKeyNotInPopulatedMap(); valueToPut = getValueNotInPopulatedMap(); } catch (UnsupportedOperationException e) { return; } - final Map mapToPut = Collections.singletonMap(keyToPut, valueToPut); + Map mapToPut = Collections.singletonMap(keyToPut, valueToPut); if (supportsPut) { int initialSize = map.size(); map.putAll(mapToPut); @@ -1147,9 +1149,9 @@ public void testPutAllNewKey() { } public void testPutAllExistingKey() { - final Map map; - final K keyToPut; - final V valueToPut; + Map map; + K keyToPut; + V valueToPut; try { map = makePopulatedMap(); valueToPut = getValueNotInPopulatedMap(); @@ -1157,7 +1159,7 @@ public void testPutAllExistingKey() { return; } keyToPut = map.keySet().iterator().next(); - final Map mapToPut = Collections.singletonMap(keyToPut, valueToPut); + Map mapToPut = Collections.singletonMap(keyToPut, valueToPut); int initialSize = map.size(); if (supportsPut) { map.putAll(mapToPut); @@ -1176,8 +1178,8 @@ public void testPutAllExistingKey() { } public void testRemove() { - final Map map; - final K keyToRemove; + Map map; + K keyToRemove; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1202,8 +1204,8 @@ public void testRemove() { } public void testRemoveMissingKey() { - final Map map; - final K keyToRemove; + Map map; + K keyToRemove; try { map = makePopulatedMap(); keyToRemove = getKeyNotInPopulatedMap(); @@ -1229,7 +1231,7 @@ public void testSize() { } public void testKeySetRemove() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1254,7 +1256,7 @@ public void testKeySetRemove() { } public void testKeySetRemoveAll() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1279,7 +1281,7 @@ public void testKeySetRemoveAll() { } public void testKeySetRetainAll() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1303,7 +1305,7 @@ public void testKeySetRetainAll() { } public void testKeySetClear() { - final Map map; + Map map; try { map = makeEitherMap(); } catch (UnsupportedOperationException e) { @@ -1325,7 +1327,7 @@ public void testKeySetClear() { } public void testKeySetRemoveAllNullFromEmpty() { - final Map map; + Map map; try { map = makeEmptyMap(); } catch (UnsupportedOperationException e) { @@ -1351,7 +1353,7 @@ public void testKeySetRemoveAllNullFromEmpty() { } public void testKeySetRetainAllNullFromEmpty() { - final Map map; + Map map; try { map = makeEmptyMap(); } catch (UnsupportedOperationException e) { @@ -1377,8 +1379,8 @@ public void testKeySetRetainAllNullFromEmpty() { } public void testValues() { - final Map map; - final Collection valueCollection; + Map map; + Collection valueCollection; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1387,7 +1389,7 @@ public void testValues() { assertInvariants(map); valueCollection = map.values(); - final V unmappedValue; + V unmappedValue; try { unmappedValue = getValueNotInPopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1399,7 +1401,7 @@ public void testValues() { } public void testValuesIteratorRemove() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1434,7 +1436,7 @@ public void testValuesIteratorRemove() { } public void testValuesRemove() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1460,8 +1462,8 @@ public void testValuesRemove() { } public void testValuesRemoveMissing() { - final Map map; - final V valueToRemove; + Map map; + V valueToRemove; try { map = makeEitherMap(); valueToRemove = getValueNotInPopulatedMap(); @@ -1485,7 +1487,7 @@ public void testValuesRemoveMissing() { } public void testValuesRemoveAll() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1513,7 +1515,7 @@ public void testValuesRemoveAll() { } public void testValuesRemoveAllNullFromEmpty() { - final Map map; + Map map; try { map = makeEmptyMap(); } catch (UnsupportedOperationException e) { @@ -1539,7 +1541,7 @@ public void testValuesRemoveAllNullFromEmpty() { } public void testValuesRetainAll() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -1567,7 +1569,7 @@ public void testValuesRetainAll() { } public void testValuesRetainAllNullFromEmpty() { - final Map map; + Map map; try { map = makeEmptyMap(); } catch (UnsupportedOperationException e) { @@ -1593,7 +1595,7 @@ public void testValuesRetainAllNullFromEmpty() { } public void testValuesClear() { - final Map map; + Map map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { diff --git a/android/guava-testlib/src/com/google/common/collect/testing/MapTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/MapTestSuiteBuilder.java index 7bb418f5a97b..7b8e40a2b1aa 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/MapTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/MapTestSuiteBuilder.java @@ -101,6 +101,8 @@ protected List createDerivedSuites( .withFeatures(computeReserializedMapFeatures(parentBuilder.getFeatures())) .named(parentBuilder.getName() + " reserialized") .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); } @@ -110,6 +112,8 @@ protected List createDerivedSuites( .withFeatures(computeEntrySetFeatures(parentBuilder.getFeatures())) .named(parentBuilder.getName() + " entrySet") .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); derivedSuites.add( @@ -117,6 +121,8 @@ protected List createDerivedSuites( .withFeatures(computeKeySetFeatures(parentBuilder.getFeatures())) .named(parentBuilder.getName() + " keys") .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); derivedSuites.add( @@ -125,6 +131,8 @@ protected List createDerivedSuites( .named(parentBuilder.getName() + " values") .withFeatures(computeValuesCollectionFeatures(parentBuilder.getFeatures())) .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); return derivedSuites; diff --git a/android/guava-testlib/src/com/google/common/collect/testing/MinimalCollection.java b/android/guava-testlib/src/com/google/common/collect/testing/MinimalCollection.java index a6ec93d1eca3..2adf0725147d 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/MinimalCollection.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/MinimalCollection.java @@ -33,12 +33,12 @@ public class MinimalCollection extends AbstractCollection { // TODO: expose allow nulls parameter? public static MinimalCollection of(E... contents) { - return new MinimalCollection(Object.class, true, contents); + return new MinimalCollection<>(Object.class, true, contents); } // TODO: use this public static MinimalCollection ofClassAndContents(Class type, E... contents) { - return new MinimalCollection(type, true, contents); + return new MinimalCollection<>(type, true, contents); } private final E[] contents; diff --git a/android/guava-testlib/src/com/google/common/collect/testing/MinimalIterable.java b/android/guava-testlib/src/com/google/common/collect/testing/MinimalIterable.java index c151c15e1319..15d48dbbd75b 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/MinimalIterable.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/MinimalIterable.java @@ -51,7 +51,7 @@ public final class MinimalIterable implements Iterable { /** Returns an iterable whose iterator returns the given elements in order. */ public static MinimalIterable of(E... elements) { // Make sure to get an unmodifiable iterator - return new MinimalIterable(Arrays.asList(elements).iterator()); + return new MinimalIterable<>(Arrays.asList(elements).iterator()); } /** @@ -59,7 +59,7 @@ public static MinimalIterable of(E... elements) { * out of the source collection at the time this method is called. */ @SuppressWarnings("unchecked") // Es come in, Es go out - public static MinimalIterable from(final Collection elements) { + public static MinimalIterable from(Collection elements) { return (MinimalIterable) of(elements.toArray()); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/MinimalSet.java b/android/guava-testlib/src/com/google/common/collect/testing/MinimalSet.java index 988dd3f95511..9a87d244d01f 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/MinimalSet.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/MinimalSet.java @@ -45,13 +45,13 @@ public static MinimalSet from(Collection contents) { public static MinimalSet ofClassAndContents( Class type, E[] emptyArrayForContents, Iterable contents) { - List setContents = new ArrayList(); + List setContents = new ArrayList<>(); for (E e : contents) { if (!setContents.contains(e)) { setContents.add(e); } } - return new MinimalSet(type, setContents.toArray(emptyArrayForContents)); + return new MinimalSet<>(type, setContents.toArray(emptyArrayForContents)); } private MinimalSet(Class type, E... contents) { diff --git a/android/guava-testlib/src/com/google/common/collect/testing/NavigableMapTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/NavigableMapTestSuiteBuilder.java index 77a198454bd8..0e1a229208e8 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/NavigableMapTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/NavigableMapTestSuiteBuilder.java @@ -116,10 +116,10 @@ public NavigableMapTestSuiteBuilder newBuilderUsing( /** Create a suite whose maps are descending views of other maps. */ private TestSuite createDescendingSuite( - final FeatureSpecificTestSuiteBuilder< + FeatureSpecificTestSuiteBuilder< ?, ? extends OneSizeTestContainerGenerator, Entry>> parentBuilder) { - final TestSortedMapGenerator delegate = + TestSortedMapGenerator delegate = (TestSortedMapGenerator) parentBuilder.getSubjectGenerator().getInnerGenerator(); List> features = new ArrayList<>(); diff --git a/android/guava-testlib/src/com/google/common/collect/testing/NavigableSetTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/NavigableSetTestSuiteBuilder.java index 38eb56e09dee..4c86ab46206c 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/NavigableSetTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/NavigableSetTestSuiteBuilder.java @@ -40,7 +40,7 @@ @GwtIncompatible public final class NavigableSetTestSuiteBuilder extends SortedSetTestSuiteBuilder { public static NavigableSetTestSuiteBuilder using(TestSortedSetGenerator generator) { - NavigableSetTestSuiteBuilder builder = new NavigableSetTestSuiteBuilder(); + NavigableSetTestSuiteBuilder builder = new NavigableSetTestSuiteBuilder<>(); builder.usingGenerator(generator); return builder; } @@ -99,10 +99,9 @@ public NavigableSetTestSuiteBuilder newBuilderUsing( /** Create a suite whose maps are descending views of other maps. */ private TestSuite createDescendingSuite( - final FeatureSpecificTestSuiteBuilder< - ?, ? extends OneSizeTestContainerGenerator, E>> + FeatureSpecificTestSuiteBuilder, E>> parentBuilder) { - final TestSetGenerator delegate = + TestSetGenerator delegate = (TestSetGenerator) parentBuilder.getSubjectGenerator().getInnerGenerator(); List> features = new ArrayList<>(); @@ -124,7 +123,7 @@ public E[] createArray(int length) { @Override public Iterable order(List insertionOrder) { - List list = new ArrayList(); + List list = new ArrayList<>(); for (E e : delegate.order(insertionOrder)) { list.add(e); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/OneSizeGenerator.java b/android/guava-testlib/src/com/google/common/collect/testing/OneSizeGenerator.java index 1b8924c07606..1ff3facc4fd4 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/OneSizeGenerator.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/OneSizeGenerator.java @@ -70,7 +70,7 @@ public Collection getSampleElements(int howMany) { @SuppressWarnings("unchecked") List allSampleElements = Arrays.asList(samples.e0(), samples.e1(), samples.e2(), samples.e3(), samples.e4()); - return new ArrayList(allSampleElements.subList(0, howMany)); + return new ArrayList<>(allSampleElements.subList(0, howMany)); } @Override diff --git a/android/guava-testlib/src/com/google/common/collect/testing/ReserializingTestCollectionGenerator.java b/android/guava-testlib/src/com/google/common/collect/testing/ReserializingTestCollectionGenerator.java index 28d6f7917dd9..923f56fd45c0 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/ReserializingTestCollectionGenerator.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/ReserializingTestCollectionGenerator.java @@ -42,7 +42,7 @@ public class ReserializingTestCollectionGenerator implements TestCollectionGe public static ReserializingTestCollectionGenerator newInstance( TestCollectionGenerator delegate) { - return new ReserializingTestCollectionGenerator(delegate); + return new ReserializingTestCollectionGenerator<>(delegate); } @Override diff --git a/android/guava-testlib/src/com/google/common/collect/testing/ReserializingTestSetGenerator.java b/android/guava-testlib/src/com/google/common/collect/testing/ReserializingTestSetGenerator.java index c92a3ff20aca..555440adc172 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/ReserializingTestSetGenerator.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/ReserializingTestSetGenerator.java @@ -35,7 +35,7 @@ public class ReserializingTestSetGenerator extends ReserializingTestCollectio } public static TestSetGenerator newInstance(TestSetGenerator delegate) { - return new ReserializingTestSetGenerator(delegate); + return new ReserializingTestSetGenerator<>(delegate); } @Override diff --git a/android/guava-testlib/src/com/google/common/collect/testing/SafeTreeSet.java b/android/guava-testlib/src/com/google/common/collect/testing/SafeTreeSet.java index 8ed48107347c..91d9fd9f750d 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/SafeTreeSet.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/SafeTreeSet.java @@ -117,7 +117,7 @@ public Iterator descendingIterator() { @Override public NavigableSet descendingSet() { - return new SafeTreeSet(delegate.descendingSet()); + return new SafeTreeSet<>(delegate.descendingSet()); } @Override @@ -137,7 +137,7 @@ public SortedSet headSet(E toElement) { @Override public NavigableSet headSet(E toElement, boolean inclusive) { - return new SafeTreeSet(delegate.headSet(checkValid(toElement), inclusive)); + return new SafeTreeSet<>(delegate.headSet(checkValid(toElement), inclusive)); } @Override @@ -198,7 +198,7 @@ public int size() { @Override public NavigableSet subSet( E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { - return new SafeTreeSet( + return new SafeTreeSet<>( delegate.subSet( checkValid(fromElement), fromInclusive, checkValid(toElement), toInclusive)); } @@ -215,7 +215,7 @@ public SortedSet tailSet(E fromElement) { @Override public NavigableSet tailSet(E fromElement, boolean inclusive) { - return new SafeTreeSet(delegate.tailSet(checkValid(fromElement), inclusive)); + return new SafeTreeSet<>(delegate.tailSet(checkValid(fromElement), inclusive)); } @Override diff --git a/android/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java index 26a2870ca9d5..4ac51a4612f1 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java @@ -78,6 +78,8 @@ protected List createDerivedSuites( .named(getName() + " reserialized") .withFeatures(computeReserializedCollectionFeatures(parentBuilder.getFeatures())) .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); } return derivedSuites; diff --git a/android/guava-testlib/src/com/google/common/collect/testing/SortedMapInterfaceTest.java b/android/guava-testlib/src/com/google/common/collect/testing/SortedMapInterfaceTest.java index 829c4cc27874..03266ab4776d 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/SortedMapInterfaceTest.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/SortedMapInterfaceTest.java @@ -56,7 +56,7 @@ protected SortedMap makeEitherMap() { } public void testTailMapWriteThrough() { - final SortedMap map; + SortedMap map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -82,7 +82,7 @@ public void testTailMapWriteThrough() { } public void testTailMapRemoveThrough() { - final SortedMap map; + SortedMap map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { @@ -105,7 +105,7 @@ public void testTailMapRemoveThrough() { } public void testTailMapClearThrough() { - final SortedMap map; + SortedMap map; try { map = makePopulatedMap(); } catch (UnsupportedOperationException e) { diff --git a/android/guava-testlib/src/com/google/common/collect/testing/SortedMapTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/SortedMapTestSuiteBuilder.java index e95383af64a6..7944aaa6a0b8 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/SortedMapTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/SortedMapTestSuiteBuilder.java @@ -105,12 +105,12 @@ public Set> getImpliedFeatures() { * these extreme values rather than relying on their regular sort ordering. */ final TestSuite createSubmapSuite( - final FeatureSpecificTestSuiteBuilder< + FeatureSpecificTestSuiteBuilder< ?, ? extends OneSizeTestContainerGenerator, Entry>> parentBuilder, - final Bound from, - final Bound to) { - final TestSortedMapGenerator delegate = + Bound from, + Bound to) { + TestSortedMapGenerator delegate = (TestSortedMapGenerator) parentBuilder.getSubjectGenerator().getInnerGenerator(); List> features = new ArrayList<>(); @@ -121,6 +121,8 @@ final TestSuite createSubmapSuite( .named(parentBuilder.getName() + " subMap " + from + "-" + to) .withFeatures(features) .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite(); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java index e97b08fc5537..2835769e33f7 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java @@ -34,7 +34,7 @@ @GwtIncompatible public class SortedSetTestSuiteBuilder extends SetTestSuiteBuilder { public static SortedSetTestSuiteBuilder using(TestSortedSetGenerator generator) { - SortedSetTestSuiteBuilder builder = new SortedSetTestSuiteBuilder(); + SortedSetTestSuiteBuilder builder = new SortedSetTestSuiteBuilder<>(); builder.usingGenerator(generator); return builder; } @@ -78,12 +78,11 @@ protected List createDerivedSuites( * these extreme values rather than relying on their regular sort ordering. */ final TestSuite createSubsetSuite( - final FeatureSpecificTestSuiteBuilder< - ?, ? extends OneSizeTestContainerGenerator, E>> + FeatureSpecificTestSuiteBuilder, E>> parentBuilder, - final Bound from, - final Bound to) { - final TestSortedSetGenerator delegate = + Bound from, + Bound to) { + TestSortedSetGenerator delegate = (TestSortedSetGenerator) parentBuilder.getSubjectGenerator().getInnerGenerator(); List> features = new ArrayList<>(parentBuilder.getFeatures()); @@ -94,6 +93,8 @@ final TestSuite createSubsetSuite( .named(parentBuilder.getName() + " subSet " + from + "-" + to) .withFeatures(features) .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite(); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/features/FeatureUtil.java b/android/guava-testlib/src/com/google/common/collect/testing/features/FeatureUtil.java index 95cbc0b3d8be..2d11a0863494 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/features/FeatureUtil.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/features/FeatureUtil.java @@ -139,12 +139,12 @@ public static TesterRequirements getTesterRequirements(Method testerMethod) */ static TesterRequirements buildTesterRequirements(Class testerClass) throws ConflictingRequirementsException { - final TesterRequirements declaredRequirements = buildDeclaredTesterRequirements(testerClass); + TesterRequirements declaredRequirements = buildDeclaredTesterRequirements(testerClass); Class baseClass = testerClass.getSuperclass(); if (baseClass == null) { return declaredRequirements; } else { - final TesterRequirements clonedBaseRequirements = + TesterRequirements clonedBaseRequirements = new TesterRequirements(getTesterRequirements(baseClass)); return incorporateRequirements(clonedBaseRequirements, declaredRequirements, testerClass); } @@ -176,8 +176,8 @@ static TesterRequirements buildTesterRequirements(Method testerMethod) private static TesterRequirements buildTesterRequirements(Annotation testerAnnotation) throws ConflictingRequirementsException { Class annotationClass = testerAnnotation.annotationType(); - final Feature[] presentFeatures; - final Feature[] absentFeatures; + Feature[] presentFeatures; + Feature[] absentFeatures; try { presentFeatures = (Feature[]) annotationClass.getMethod("value").invoke(testerAnnotation); absentFeatures = (Feature[]) annotationClass.getMethod("absent").invoke(testerAnnotation); diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultimapTester.java b/android/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultimapTester.java index 7b7801db2633..7f649e757165 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultimapTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultimapTester.java @@ -48,8 +48,8 @@ protected M multimap() { /** @return an array of the proper size with {@code null} as the key of the middle element. */ protected Entry[] createArrayWithNullKey() { Entry[] array = createSamplesArray(); - final int nullKeyLocation = getNullLocation(); - final Entry oldEntry = array[nullKeyLocation]; + int nullKeyLocation = getNullLocation(); + Entry oldEntry = array[nullKeyLocation]; array[nullKeyLocation] = Helpers.mapEntry(null, oldEntry.getValue()); return array; } @@ -57,8 +57,8 @@ protected Entry[] createArrayWithNullKey() { /** @return an array of the proper size with {@code null} as the value of the middle element. */ protected Entry[] createArrayWithNullValue() { Entry[] array = createSamplesArray(); - final int nullValueLocation = getNullLocation(); - final Entry oldEntry = array[nullValueLocation]; + int nullValueLocation = getNullLocation(); + Entry oldEntry = array[nullValueLocation]; array[nullValueLocation] = Helpers.mapEntry(oldEntry.getKey(), null); return array; } @@ -69,7 +69,7 @@ protected Entry[] createArrayWithNullValue() { */ protected Entry[] createArrayWithNullKeyAndValue() { Entry[] array = createSamplesArray(); - final int nullValueLocation = getNullLocation(); + int nullValueLocation = getNullLocation(); array[nullValueLocation] = Helpers.mapEntry(null, null); return array; } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/BiMapTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/google/BiMapTestSuiteBuilder.java index fa21a71a536d..0821fb0b554e 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/BiMapTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/BiMapTestSuiteBuilder.java @@ -88,6 +88,8 @@ protected List createDerivedSuites( .suppressing(parentBuilder.getSuppressedTests()) .suppressing(SetCreationTester.class.getMethods()) // BiMap.entrySet() duplicate-handling behavior is too confusing for SetCreationTester + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); /* * TODO(cpovirk): the Map tests duplicate most of this effort by using a @@ -101,6 +103,8 @@ protected List createDerivedSuites( .suppressing(parentBuilder.getSuppressedTests()) .suppressing(SetCreationTester.class.getMethods()) // BiMap.values() duplicate-handling behavior is too confusing for SetCreationTester + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); if (!parentBuilder.getFeatures().contains(NoRecurse.INVERSE)) { derived.add( @@ -109,6 +113,8 @@ protected List createDerivedSuites( .withFeatures(computeInverseFeatures(parentBuilder.getFeatures())) .named(parentBuilder.getName() + " inverse") .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/DerivedGoogleCollectionGenerators.java b/android/guava-testlib/src/com/google/common/collect/testing/google/DerivedGoogleCollectionGenerators.java index bbeefd278e00..35579a01d758 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/DerivedGoogleCollectionGenerators.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/DerivedGoogleCollectionGenerators.java @@ -159,9 +159,9 @@ public static class BiMapValueSetGenerator public BiMapValueSetGenerator( OneSizeTestContainerGenerator, Entry> mapGenerator) { this.mapGenerator = mapGenerator; - final SampleElements> mapSamples = this.mapGenerator.samples(); + SampleElements> mapSamples = this.mapGenerator.samples(); this.samples = - new SampleElements( + new SampleElements<>( mapSamples.e0().getValue(), mapSamples.e1().getValue(), mapSamples.e2().getValue(), @@ -194,7 +194,7 @@ public Set create(Object... elements) { @Override public V[] createArray(int length) { - final V[] vs = + V[] vs = ((TestBiMapGenerator) mapGenerator.getInnerGenerator()).createValueArray(length); return vs; } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java b/android/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java index bb84ea15f931..35063e815d0b 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java @@ -54,7 +54,7 @@ protected Map create(Entry[] entries) { for (Entry entry : entries) { builder.put(entry.getKey(), entry.getValue()); } - return builder.build(); + return builder.buildOrThrow(); } } @@ -86,7 +86,7 @@ public Collection create(UnhashableObject[] elements) { for (UnhashableObject value : elements) { builder.put(key++, value); } - return builder.build().values(); + return builder.buildOrThrow().values(); } } @@ -97,7 +97,7 @@ public List create(String[] elements) { for (int i = 0; i < elements.length; i++) { builder.put(elements[i], i); } - return builder.build().keySet().asList(); + return builder.buildOrThrow().keySet().asList(); } } @@ -108,7 +108,7 @@ public List create(String[] elements) { for (int i = 0; i < elements.length; i++) { builder.put(i, elements[i]); } - return builder.build().values().asList(); + return builder.buildOrThrow().values().asList(); } } @@ -144,7 +144,7 @@ public List> create(Object... elements) { Entry entry = (Entry) o; builder.put(entry); } - return builder.build().entrySet().asList(); + return builder.buildOrThrow().entrySet().asList(); } } @@ -210,7 +210,7 @@ public Map> create(Object... elements) { Integer value = Iterables.getOnlyElement(entry.getValue()); builder.put(entry.getKey(), value); } - return builder.build().asMultimap().asMap(); + return builder.buildOrThrow().asMultimap().asMap(); } @Override diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/MultimapTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/google/MultimapTestSuiteBuilder.java index 8504940bb6fb..97c24c98d277 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/MultimapTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/MultimapTestSuiteBuilder.java @@ -115,6 +115,8 @@ protected List createDerivedSuites( .withFeatures(computeReserializedMultimapFeatures(parentBuilder.getFeatures())) .named(parentBuilder.getName() + " reserialized") .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); } @@ -123,6 +125,8 @@ protected List createDerivedSuites( .withFeatures(computeAsMapFeatures(parentBuilder.getFeatures())) .named(parentBuilder.getName() + ".asMap") .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); derivedSuites.add(computeEntriesTestSuite(parentBuilder)); @@ -153,6 +157,8 @@ TestSuite computeEntriesTestSuite( .withFeatures(computeEntriesFeatures(parentBuilder.getFeatures())) .named(parentBuilder.getName() + ".entries") .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite(); } @@ -164,6 +170,8 @@ TestSuite computeMultimapGetTestSuite( .withFeatures(computeMultimapGetFeatures(parentBuilder.getFeatures())) .named(parentBuilder.getName() + ".get[key]") .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite(); } @@ -179,6 +187,8 @@ TestSuite computeMultimapAsMapGetTestSuite( .withFeatures(features) .named(parentBuilder.getName() + ".asMap[].get[key]") .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite(); } } @@ -191,6 +201,8 @@ TestSuite computeKeysTestSuite( .withFeatures(computeKeysFeatures(parentBuilder.getFeatures())) .named(parentBuilder.getName() + ".keys") .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite(); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetNavigationTester.java b/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetNavigationTester.java index b65cd967ac0d..ce8e283a9c3e 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetNavigationTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetNavigationTester.java @@ -82,7 +82,7 @@ public void setUp() throws Exception { @SuppressWarnings("unchecked") // Needed to stop Eclipse whining private void resetWithHole() { - List container = new ArrayList(); + List container = new ArrayList<>(); container.addAll(Collections.nCopies(a.getCount(), a.getElement())); container.addAll(Collections.nCopies(c.getCount(), c.getElement())); super.resetContainer(getSubjectGenerator().create(container.toArray())); diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java index 266daa4621b1..d6a665c14bd4 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java @@ -130,6 +130,8 @@ protected List createDerivedSuites( .named(getName() + ".entrySet") .withFeatures(computeEntrySetFeatures(parentBuilder.getFeatures())) .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); } @@ -140,6 +142,8 @@ protected List createDerivedSuites( .named(getName() + " reserialized") .withFeatures(computeReserializedMultisetFeatures(parentBuilder.getFeatures())) .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite()); } return derivedSuites; @@ -153,6 +157,8 @@ TestSuite createElementSetTestSuite( .named(getName() + ".elementSet") .withFeatures(computeElementSetFeatures(parentBuilder.getFeatures())) .suppressing(parentBuilder.getSuppressedTests()) + .withSetUp(parentBuilder.getSetUp()) + .withTearDown(parentBuilder.getTearDown()) .createTestSuite(); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapAsMapTester.java b/android/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapAsMapTester.java index 49187dd1dffe..6e7995720846 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapAsMapTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapAsMapTester.java @@ -58,7 +58,7 @@ public void testAsMapGetImplementsSet() { @MapFeature.Require(SUPPORTS_REMOVE) public void testAsMapRemoveImplementsSet() { - List keys = new ArrayList(multimap().keySet()); + List keys = new ArrayList<>(multimap().keySet()); for (K key : keys) { resetCollection(); assertTrue(multimap().asMap().remove(key) instanceof Set); diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java index dafd52187df4..b44494b81ddf 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java @@ -56,7 +56,7 @@ @GwtIncompatible public class SortedMultisetTestSuiteBuilder extends MultisetTestSuiteBuilder { public static SortedMultisetTestSuiteBuilder using(TestMultisetGenerator generator) { - SortedMultisetTestSuiteBuilder result = new SortedMultisetTestSuiteBuilder(); + SortedMultisetTestSuiteBuilder result = new SortedMultisetTestSuiteBuilder<>(); result.usingGenerator(generator); return result; } @@ -138,8 +138,8 @@ List createDerivedSuites(SortedMultisetTestSuiteBuilder parentBuil } private TestSuite createSubMultisetSuite( - SortedMultisetTestSuiteBuilder parentBuilder, final Bound from, final Bound to) { - final TestMultisetGenerator delegate = + SortedMultisetTestSuiteBuilder parentBuilder, Bound from, Bound to) { + TestMultisetGenerator delegate = (TestMultisetGenerator) parentBuilder.getSubjectGenerator(); Set> features = new HashSet<>(); @@ -152,15 +152,15 @@ private TestSuite createSubMultisetSuite( } SortedMultiset emptyMultiset = (SortedMultiset) delegate.create(); - final Comparator comparator = emptyMultiset.comparator(); + Comparator comparator = emptyMultiset.comparator(); SampleElements samples = delegate.samples(); @SuppressWarnings("unchecked") List samplesList = Arrays.asList(samples.e0(), samples.e1(), samples.e2(), samples.e3(), samples.e4()); Collections.sort(samplesList, comparator); - final E firstInclusive = samplesList.get(0); - final E lastInclusive = samplesList.get(samplesList.size() - 1); + E firstInclusive = samplesList.get(0); + E lastInclusive = samplesList.get(samplesList.size() - 1); return SortedMultisetTestSuiteBuilder.using( new ForwardingTestMultisetGenerator(delegate) { @@ -187,7 +187,7 @@ public SortedMultiset create(Object... entries) { } // the regular values should be visible after filtering - List allEntries = new ArrayList(); + List allEntries = new ArrayList<>(); allEntries.addAll(extremeValues); allEntries.addAll(normalValues); SortedMultiset multiset = @@ -234,7 +234,7 @@ private List getExtremeValues() { } private TestSuite createDescendingSuite(SortedMultisetTestSuiteBuilder parentBuilder) { - final TestMultisetGenerator delegate = + TestMultisetGenerator delegate = (TestMultisetGenerator) parentBuilder.getSubjectGenerator(); Set> features = new HashSet<>(); @@ -263,7 +263,7 @@ public Iterable order(List insertionOrder) { } private TestSuite createReserializedSuite(SortedMultisetTestSuiteBuilder parentBuilder) { - final TestMultisetGenerator delegate = + TestMultisetGenerator delegate = (TestMultisetGenerator) parentBuilder.getSubjectGenerator(); Set> features = new HashSet<>(parentBuilder.getFeatures()); diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapAsMapTester.java b/android/guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapAsMapTester.java index 1c00f0970102..e95b74f84b0c 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapAsMapTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapAsMapTester.java @@ -52,7 +52,7 @@ public void testAsMapGetImplementsSortedSet() { @MapFeature.Require(SUPPORTS_REMOVE) public void testAsMapRemoveImplementsSortedSet() { - List keys = new ArrayList(multimap().keySet()); + List keys = new ArrayList<>(multimap().keySet()); for (K key : keys) { resetCollection(); SortedSet valueSet = (SortedSet) multimap().asMap().remove(key); diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/UnmodifiableCollectionTests.java b/android/guava-testlib/src/com/google/common/collect/testing/google/UnmodifiableCollectionTests.java index 005746f4be20..40b2c859d20c 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/google/UnmodifiableCollectionTests.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/google/UnmodifiableCollectionTests.java @@ -201,7 +201,7 @@ public static void assertSetIsUnmodifiable(Set set, E sampleElement) { * @param sampleElement an element of the same type as that contained by {@code multiset}. {@code * multiset} may or may not have {@code sampleElement} as a member. */ - public static void assertMultisetIsUnmodifiable(Multiset multiset, final E sampleElement) { + public static void assertMultisetIsUnmodifiable(Multiset multiset, E sampleElement) { Multiset copy = LinkedHashMultiset.create(multiset); assertCollectionsAreEquivalent(multiset, copy); @@ -264,7 +264,7 @@ public E getElement() { * multimap} may or may not have {@code sampleValue} as a key. */ public static void assertMultimapIsUnmodifiable( - Multimap multimap, final K sampleKey, final V sampleValue) { + Multimap multimap, K sampleKey, V sampleValue) { List> originalEntries = Collections.unmodifiableList(Lists.newArrayList(multimap.entries())); diff --git a/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java b/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java index b17049709e81..1699fe19dced 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java @@ -51,7 +51,7 @@ @Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. public class CollectionIteratorTester extends AbstractCollectionTester { public void testIterator() { - List iteratorElements = new ArrayList(); + List iteratorElements = new ArrayList<>(); for (E element : collection) { // uses iterator() iteratorElements.add(element); } @@ -60,7 +60,7 @@ public void testIterator() { @CollectionFeature.Require(KNOWN_ORDER) public void testIterationOrdering() { - List iteratorElements = new ArrayList(); + List iteratorElements = new ArrayList<>(); for (E element : collection) { // uses iterator() iteratorElements.add(element); } @@ -72,7 +72,7 @@ public void testIterationOrdering() { @CollectionSize.Require(absent = ZERO) public void testIterator_nullElement() { initCollectionWithNullElement(); - List iteratorElements = new ArrayList(); + List iteratorElements = new ArrayList<>(); for (E element : collection) { // uses iterator() iteratorElements.add(element); } diff --git a/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToArrayTester.java b/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToArrayTester.java index 83a4ceac869d..b40fc3636943 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToArrayTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToArrayTester.java @@ -48,8 +48,8 @@ public void testToArray_noArgs() { } /** - * {@link Collection#toArray(Object[])} says: "Note that toArray(new Object[0]) is - * identical in function to toArray()." + * {@link Collection#toArray(Object[])} says: "Note that {@code toArray(new Object[0])} is + * identical in function to {@code toArray()}." * *

    For maximum effect, the collection under test should be created from an element array of a * type other than {@code Object[]}. diff --git a/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java b/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java index 39016169d986..8b056b4cb1a1 100644 --- a/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java +++ b/android/guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java @@ -218,7 +218,7 @@ public void testPollLastUnsupported() { @CollectionSize.Require(SEVERAL) public void testDescendingNavigation() { - List descending = new ArrayList(); + List descending = new ArrayList<>(); for (Iterator i = navigableSet.descendingIterator(); i.hasNext(); ) { descending.add(i.next()); } diff --git a/android/guava-testlib/src/com/google/common/escape/testing/EscaperAsserts.java b/android/guava-testlib/src/com/google/common/escape/testing/EscaperAsserts.java index 3920afe4c137..31ac2015dd04 100644 --- a/android/guava-testlib/src/com/google/common/escape/testing/EscaperAsserts.java +++ b/android/guava-testlib/src/com/google/common/escape/testing/EscaperAsserts.java @@ -18,7 +18,6 @@ import static com.google.common.escape.Escapers.computeReplacement; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtCompatible; import com.google.common.escape.CharEscaper; import com.google.common.escape.Escaper; @@ -32,7 +31,6 @@ * @author David Beaumont * @since 15.0 */ -@Beta @GwtCompatible public final class EscaperAsserts { private EscaperAsserts() {} diff --git a/android/guava-testlib/src/com/google/common/testing/AbstractPackageSanityTests.java b/android/guava-testlib/src/com/google/common/testing/AbstractPackageSanityTests.java index 962b15f6d677..1e31bbfb408f 100644 --- a/android/guava-testlib/src/com/google/common/testing/AbstractPackageSanityTests.java +++ b/android/guava-testlib/src/com/google/common/testing/AbstractPackageSanityTests.java @@ -116,12 +116,7 @@ public abstract class AbstractPackageSanityTests extends TestCase { * @since 19.0 */ public static final Predicate> UNDERSCORE_IN_NAME = - new Predicate>() { - @Override - public boolean apply(Class c) { - return c.getSimpleName().contains("_"); - } - }; + (Class c) -> c.getSimpleName().contains("_"); /* The names of the expected method that tests null checks. */ private static final ImmutableList NULL_TEST_METHOD_NAMES = @@ -152,12 +147,7 @@ public boolean apply(Class c) { private final ClassSanityTester tester = new ClassSanityTester(); private Visibility visibility = Visibility.PACKAGE; private Predicate> classFilter = - new Predicate>() { - @Override - public boolean apply(Class cls) { - return visibility.isVisible(cls.getModifiers()); - } - }; + (Class cls) -> visibility.isVisible(cls.getModifiers()); /** * Restricts the sanity tests for public API only. By default, package-private API are also @@ -415,8 +405,8 @@ private static boolean isEqualsDefined(Class cls) { abstract static class Chopper { - final Chopper or(final Chopper you) { - final Chopper i = this; + final Chopper or(Chopper you) { + Chopper i = this; return new Chopper() { @Override Optional chop(String str) { @@ -427,7 +417,7 @@ Optional chop(String str) { abstract Optional chop(String str); - static Chopper suffix(final String suffix) { + static Chopper suffix(String suffix) { return new Chopper() { @Override Optional chop(String str) { diff --git a/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java b/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java index 01904d6c220c..26f4df4749af 100644 --- a/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java +++ b/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtIncompatible; import com.google.common.base.CharMatcher; import com.google.common.base.Charsets; @@ -74,6 +73,7 @@ import com.google.common.primitives.Primitives; import com.google.common.primitives.UnsignedInteger; import com.google.common.primitives.UnsignedLong; +import com.google.errorprone.annotations.Keep; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -142,7 +142,7 @@ import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Supplies an arbitrary "default" instance for a wide range of types, often useful in testing @@ -166,7 +166,6 @@ * @author Ben Yu * @since 12.0 */ -@Beta @GwtIncompatible public final class ArbitraryInstances { @@ -327,7 +326,7 @@ private static void setImplementation(Class type, Class impl } @SuppressWarnings("unchecked") // it's a subtype map - @NullableDecl + @CheckForNull private static Class getImplementation(Class type) { return (Class) implementations.get(type); } @@ -338,7 +337,7 @@ private static Class getImplementation(Class type) { * Returns an arbitrary instance for {@code type}, or {@code null} if no arbitrary instance can be * determined. */ - @NullableDecl + @CheckForNull public static T get(Class type) { T defaultValue = DEFAULTS.getInstance(type); if (defaultValue != null) { @@ -386,7 +385,7 @@ public static T get(Class type) { } } - @NullableDecl + @CheckForNull private static T arbitraryConstantInstanceOrNull(Class type) { Field[] fields = type.getDeclaredFields(); Arrays.sort(fields, BY_FIELD_NAME); @@ -430,6 +429,7 @@ public InMemoryPrintWriter() { } public static final class DeterministicRandom extends Random { + @Keep public DeterministicRandom() { super(0); } diff --git a/android/guava-testlib/src/com/google/common/testing/ClassSanityTester.java b/android/guava-testlib/src/com/google/common/testing/ClassSanityTester.java index 55f167eddd86..09317854571a 100644 --- a/android/guava-testlib/src/com/google/common/testing/ClassSanityTester.java +++ b/android/guava-testlib/src/com/google/common/testing/ClassSanityTester.java @@ -50,9 +50,9 @@ import java.util.List; import java.util.Map.Entry; import java.util.Set; +import javax.annotation.CheckForNull; import junit.framework.Assert; import junit.framework.AssertionFailedError; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Tester that runs automated sanity tests for any given class. A typical use case is to test static @@ -334,7 +334,7 @@ void doTestEquals(Class cls) * @return The instantiated instance, or {@code null} if the class has no non-private constructor * or factory method to be constructed. */ - @NullableDecl + @CheckForNull T instantiate(Class cls) throws ParameterNotInstantiableException, IllegalAccessException, InvocationTargetException, FactoryMethodReturnsNullException { @@ -383,7 +383,7 @@ T instantiate(Class cls) * class, preventing its methods from being accessible. * @throws InvocationTargetException if a static method threw exception. */ - @NullableDecl + @CheckForNull private T instantiate(Invokable factory) throws ParameterNotInstantiableException, InvocationTargetException, IllegalAccessException { return invoke(factory, getDummyArguments(factory)); @@ -664,7 +664,7 @@ Object interfaceMethodCalled(Class interfaceType, Method method) { return generator; } - @NullableDecl + @CheckForNull private static Object generateDummyArg(Parameter param, FreshValueGenerator generator) throws ParameterNotInstantiableException { if (isNullable(param)) { @@ -761,7 +761,7 @@ private static T createInstance(Invokable factory, List a return instance; } - @NullableDecl + @CheckForNull private static T invoke(Invokable factory, List args) throws InvocationTargetException, IllegalAccessException { T returnValue = factory.invoke(null, args.toArray()); diff --git a/android/guava-testlib/src/com/google/common/testing/EqualsTester.java b/android/guava-testlib/src/com/google/common/testing/EqualsTester.java index 2c8e08b87c57..9c93c9a492a1 100644 --- a/android/guava-testlib/src/com/google/common/testing/EqualsTester.java +++ b/android/guava-testlib/src/com/google/common/testing/EqualsTester.java @@ -20,7 +20,6 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtCompatible; import com.google.common.base.Equivalence; import com.google.common.collect.ImmutableList; @@ -74,7 +73,6 @@ * @author Jige Yu * @since 10.0 */ -@Beta @GwtCompatible public final class EqualsTester { private static final int REPETITIONS = 3; @@ -122,7 +120,7 @@ private void testItems() { assertTrue( item + " must not be Object#equals to an arbitrary object of another class", !item.equals(NotAnInstance.EQUAL_TO_NOTHING)); - assertEquals(item + " must be Object#equals to itself", item, item); + assertTrue(item + " must be Object#equals to itself", item.equals(item)); assertEquals( "the Object#hashCode of " + item + " must be consistent", item.hashCode(), diff --git a/android/guava-testlib/src/com/google/common/testing/EquivalenceTester.java b/android/guava-testlib/src/com/google/common/testing/EquivalenceTester.java index ce1dc98c440e..8de2625d0ed6 100644 --- a/android/guava-testlib/src/com/google/common/testing/EquivalenceTester.java +++ b/android/guava-testlib/src/com/google/common/testing/EquivalenceTester.java @@ -20,7 +20,6 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtCompatible; import com.google.common.base.Equivalence; import com.google.common.collect.ImmutableList; @@ -49,7 +48,6 @@ * @author Gregory Kick * @since 10.0 */ -@Beta @GwtCompatible public final class EquivalenceTester { private static final int REPETITIONS = 3; @@ -60,12 +58,11 @@ public final class EquivalenceTester { private EquivalenceTester(Equivalence equivalence) { this.equivalence = checkNotNull(equivalence); - this.delegate = - new RelationshipTester(equivalence, "equivalent", "hash", new ItemReporter()); + this.delegate = new RelationshipTester<>(equivalence, "equivalent", "hash", new ItemReporter()); } public static EquivalenceTester of(Equivalence equivalence) { - return new EquivalenceTester(equivalence); + return new EquivalenceTester<>(equivalence); } /** diff --git a/android/guava-testlib/src/com/google/common/testing/FakeTicker.java b/android/guava-testlib/src/com/google/common/testing/FakeTicker.java index 698db6a002d5..573635393e74 100644 --- a/android/guava-testlib/src/com/google/common/testing/FakeTicker.java +++ b/android/guava-testlib/src/com/google/common/testing/FakeTicker.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtCompatible; import com.google.common.base.Ticker; import java.util.concurrent.TimeUnit; @@ -35,7 +34,6 @@ * @author Jige Yu * @since 10.0 */ -@Beta @GwtCompatible public class FakeTicker extends Ticker { diff --git a/android/guava-testlib/src/com/google/common/testing/ForwardingWrapperTester.java b/android/guava-testlib/src/com/google/common/testing/ForwardingWrapperTester.java index 4ee461eb245f..605d3a055b28 100644 --- a/android/guava-testlib/src/com/google/common/testing/ForwardingWrapperTester.java +++ b/android/guava-testlib/src/com/google/common/testing/ForwardingWrapperTester.java @@ -22,7 +22,6 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.fail; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Function; import com.google.common.base.Throwables; @@ -53,7 +52,6 @@ * @author Ben Yu * @since 14.0 */ -@Beta @GwtIncompatible public final class ForwardingWrapperTester { @@ -129,7 +127,7 @@ private static void testSuccessfulForwarding( private static void testExceptionPropagation( Class interfaceType, Method method, Function wrapperFunction) { - final RuntimeException exception = new RuntimeException(); + RuntimeException exception = new RuntimeException(); T proxy = Reflection.newProxy( interfaceType, @@ -175,7 +173,7 @@ private static void testToString( private static Object[] getParameterValues(Method method) { FreshValueGenerator paramValues = new FreshValueGenerator(); - final List passedArgs = Lists.newArrayList(); + List passedArgs = Lists.newArrayList(); for (Class paramType : method.getParameterTypes()) { passedArgs.add(paramValues.generateFresh(paramType)); } diff --git a/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java b/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java index 21e25cb96c93..259f50c45214 100644 --- a/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java +++ b/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java @@ -118,7 +118,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Generates fresh instances of types that are different from each other (if possible). @@ -137,7 +137,7 @@ class FreshValueGenerator { builder.put(method.getReturnType(), method); } } - GENERATORS = builder.build(); + GENERATORS = builder.buildOrThrow(); } private static final ImmutableMap, Method> EMPTY_GENERATORS; @@ -149,7 +149,7 @@ class FreshValueGenerator { builder.put(method.getReturnType(), method); } } - EMPTY_GENERATORS = builder.build(); + EMPTY_GENERATORS = builder.buildOrThrow(); } private final AtomicInteger freshness = new AtomicInteger(1); @@ -175,7 +175,7 @@ final void addSampleInstances(Class type, Iterable instances *
  • null if no value can be generated. * */ - @NullableDecl + @CheckForNull final Object generateFresh(TypeToken type) { Object generated = generate(type); if (generated != null) { @@ -184,7 +184,7 @@ final Object generateFresh(TypeToken type) { return generated; } - @NullableDecl + @CheckForNull final T generateFresh(Class type) { return Primitives.wrap(type).cast(generateFresh(TypeToken.of(type))); } @@ -299,7 +299,7 @@ public int hashCode() { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof FreshInvocationHandler) { FreshInvocationHandler that = (FreshInvocationHandler) obj; return identity == that.identity; @@ -354,7 +354,7 @@ private static String paramString(Class type, int i) { private @interface Empty {} @Generates - private Class generateClass() { + Class generateClass() { return pickInstance( ImmutableList.of( int.class, long.class, void.class, Object.class, Object[].class, Iterable.class), @@ -362,147 +362,147 @@ private Class generateClass() { } @Generates - private Object generateObject() { + Object generateObject() { return generateString(); } @Generates - private Number generateNumber() { + Number generateNumber() { return generateInt(); } @Generates - private int generateInt() { + int generateInt() { return freshness.get(); } @Generates - private Integer generateInteger() { + Integer generateInteger() { return new Integer(generateInt()); } @Generates - private long generateLong() { + long generateLong() { return generateInt(); } @Generates - private Long generateLongObject() { + Long generateLongObject() { return new Long(generateLong()); } @Generates - private float generateFloat() { + float generateFloat() { return generateInt(); } @Generates - private Float generateFloatObject() { + Float generateFloatObject() { return new Float(generateFloat()); } @Generates - private double generateDouble() { + double generateDouble() { return generateInt(); } @Generates - private Double generateDoubleObject() { + Double generateDoubleObject() { return new Double(generateDouble()); } @Generates - private short generateShort() { + short generateShort() { return (short) generateInt(); } @Generates - private Short generateShortObject() { + Short generateShortObject() { return new Short(generateShort()); } @Generates - private byte generateByte() { + byte generateByte() { return (byte) generateInt(); } @Generates - private Byte generateByteObject() { + Byte generateByteObject() { return new Byte(generateByte()); } @Generates - private char generateChar() { + char generateChar() { return generateString().charAt(0); } @Generates - private Character generateCharacter() { + Character generateCharacter() { return new Character(generateChar()); } @Generates - private boolean generateBoolean() { + boolean generateBoolean() { return generateInt() % 2 == 0; } @Generates - private Boolean generateBooleanObject() { + Boolean generateBooleanObject() { return new Boolean(generateBoolean()); } @Generates - private UnsignedInteger generateUnsignedInteger() { + UnsignedInteger generateUnsignedInteger() { return UnsignedInteger.fromIntBits(generateInt()); } @Generates - private UnsignedLong generateUnsignedLong() { + UnsignedLong generateUnsignedLong() { return UnsignedLong.fromLongBits(generateLong()); } @Generates - private BigInteger generateBigInteger() { + BigInteger generateBigInteger() { return BigInteger.valueOf(generateInt()); } @Generates - private BigDecimal generateBigDecimal() { + BigDecimal generateBigDecimal() { return BigDecimal.valueOf(generateInt()); } @Generates - private CharSequence generateCharSequence() { + CharSequence generateCharSequence() { return generateString(); } @Generates - private String generateString() { + String generateString() { return Integer.toString(generateInt()); } @Generates - private Comparable generateComparable() { + Comparable generateComparable() { return generateString(); } @Generates - private Pattern generatePattern() { + Pattern generatePattern() { return Pattern.compile(generateString()); } @Generates - private Charset generateCharset() { + Charset generateCharset() { return pickInstance(Charset.availableCharsets().values(), Charsets.UTF_8); } @Generates - private Locale generateLocale() { + Locale generateLocale() { return pickInstance(Locale.getAvailableLocales(), Locale.US); } @Generates - private Currency generateCurrency() { + Currency generateCurrency() { try { Method method = Currency.class.getMethod("getAvailableCurrencies"); @SuppressWarnings("unchecked") // getAvailableCurrencies() returns Set. @@ -538,27 +538,27 @@ private Currency preJava7FreshCurrency() { // common.base @Empty - private com.google.common.base.Optional generateGoogleOptional() { + com.google.common.base.Optional generateGoogleOptional() { return com.google.common.base.Optional.absent(); } @Generates - private com.google.common.base.Optional generateGoogleOptional(T value) { + com.google.common.base.Optional generateGoogleOptional(T value) { return com.google.common.base.Optional.of(value); } @Generates - private Joiner generateJoiner() { + Joiner generateJoiner() { return Joiner.on(generateString()); } @Generates - private Splitter generateSplitter() { + Splitter generateSplitter() { return Splitter.on(generateString()); } @Generates - private Equivalence generateEquivalence() { + Equivalence generateEquivalence() { return new Equivalence() { @Override protected boolean doEquivalent(T a, T b) { @@ -580,7 +580,7 @@ public String toString() { } @Generates - private CharMatcher generateCharMatcher() { + CharMatcher generateCharMatcher() { return new CharMatcher() { @Override public boolean matches(char c) { @@ -597,7 +597,7 @@ public String toString() { } @Generates - private Ticker generateTicker() { + Ticker generateTicker() { return new Ticker() { @Override public long read() { @@ -615,12 +615,12 @@ public String toString() { // collect @Generates - private Comparator generateComparator() { + Comparator generateComparator() { return generateOrdering(); } @Generates - private Ordering generateOrdering() { + Ordering generateOrdering() { return new Ordering() { @Override public int compare(T left, T right) { @@ -637,279 +637,283 @@ public String toString() { } @Empty - private static > Range generateRange() { + static > Range generateRange() { return Range.all(); } @Generates - private static > Range generateRange(C freshElement) { + static > Range generateRange(C freshElement) { return Range.singleton(freshElement); } @Generates - private static Iterable generateIterable(E freshElement) { + static Iterable generateIterable(@CheckForNull E freshElement) { return generateList(freshElement); } @Generates - private static Collection generateCollection(E freshElement) { + static Collection generateCollection(@CheckForNull E freshElement) { return generateList(freshElement); } @Generates - private static List generateList(E freshElement) { + static List generateList(@CheckForNull E freshElement) { return generateArrayList(freshElement); } @Generates - private static ArrayList generateArrayList(E freshElement) { + static ArrayList generateArrayList(@CheckForNull E freshElement) { ArrayList list = Lists.newArrayList(); list.add(freshElement); return list; } @Generates - private static LinkedList generateLinkedList(E freshElement) { + static LinkedList generateLinkedList(@CheckForNull E freshElement) { LinkedList list = Lists.newLinkedList(); list.add(freshElement); return list; } @Generates - private static ImmutableList generateImmutableList(E freshElement) { + static ImmutableList generateImmutableList(E freshElement) { return ImmutableList.of(freshElement); } @Generates - private static ImmutableCollection generateImmutableCollection(E freshElement) { + static ImmutableCollection generateImmutableCollection(E freshElement) { return generateImmutableList(freshElement); } @Generates - private static Set generateSet(E freshElement) { + static Set generateSet(@CheckForNull E freshElement) { return generateHashSet(freshElement); } @Generates - private static HashSet generateHashSet(E freshElement) { + static HashSet generateHashSet(@CheckForNull E freshElement) { return generateLinkedHashSet(freshElement); } @Generates - private static LinkedHashSet generateLinkedHashSet(E freshElement) { + static LinkedHashSet generateLinkedHashSet(@CheckForNull E freshElement) { LinkedHashSet set = Sets.newLinkedHashSet(); set.add(freshElement); return set; } @Generates - private static ImmutableSet generateImmutableSet(E freshElement) { + static ImmutableSet generateImmutableSet(E freshElement) { return ImmutableSet.of(freshElement); } @Generates - private static > SortedSet generateSortedSet(E freshElement) { + static > SortedSet generateSortedSet(E freshElement) { return generateNavigableSet(freshElement); } @Generates - private static > NavigableSet generateNavigableSet( - E freshElement) { + static > NavigableSet generateNavigableSet(E freshElement) { return generateTreeSet(freshElement); } @Generates - private static > TreeSet generateTreeSet(E freshElement) { + static > TreeSet generateTreeSet(E freshElement) { TreeSet set = Sets.newTreeSet(); set.add(freshElement); return set; } @Generates - private static > ImmutableSortedSet generateImmutableSortedSet( + static > ImmutableSortedSet generateImmutableSortedSet( E freshElement) { return ImmutableSortedSet.of(freshElement); } @Generates - private static Multiset generateMultiset(E freshElement) { + static Multiset generateMultiset(@CheckForNull E freshElement) { return generateHashMultiset(freshElement); } @Generates - private static HashMultiset generateHashMultiset(E freshElement) { + static HashMultiset generateHashMultiset(@CheckForNull E freshElement) { HashMultiset multiset = HashMultiset.create(); multiset.add(freshElement); return multiset; } @Generates - private static LinkedHashMultiset generateLinkedHashMultiset(E freshElement) { + static LinkedHashMultiset generateLinkedHashMultiset(@CheckForNull E freshElement) { LinkedHashMultiset multiset = LinkedHashMultiset.create(); multiset.add(freshElement); return multiset; } @Generates - private static ImmutableMultiset generateImmutableMultiset(E freshElement) { + static ImmutableMultiset generateImmutableMultiset(E freshElement) { return ImmutableMultiset.of(freshElement); } @Generates - private static > SortedMultiset generateSortedMultiset( - E freshElement) { + static > SortedMultiset generateSortedMultiset(E freshElement) { return generateTreeMultiset(freshElement); } @Generates - private static > TreeMultiset generateTreeMultiset(E freshElement) { + static > TreeMultiset generateTreeMultiset(E freshElement) { TreeMultiset multiset = TreeMultiset.create(); multiset.add(freshElement); return multiset; } @Generates - private static > - ImmutableSortedMultiset generateImmutableSortedMultiset(E freshElement) { + static > ImmutableSortedMultiset generateImmutableSortedMultiset( + E freshElement) { return ImmutableSortedMultiset.of(freshElement); } @Generates - private static Map generateMap(K key, V value) { + static Map generateMap(@CheckForNull K key, @CheckForNull V value) { return generateHashdMap(key, value); } @Generates - private static HashMap generateHashdMap(K key, V value) { + static HashMap generateHashdMap(@CheckForNull K key, @CheckForNull V value) { return generateLinkedHashMap(key, value); } @Generates - private static LinkedHashMap generateLinkedHashMap(K key, V value) { + static LinkedHashMap generateLinkedHashMap( + @CheckForNull K key, @CheckForNull V value) { LinkedHashMap map = Maps.newLinkedHashMap(); map.put(key, value); return map; } @Generates - private static ImmutableMap generateImmutableMap(K key, V value) { + static ImmutableMap generateImmutableMap(K key, V value) { return ImmutableMap.of(key, value); } @Empty - private static ConcurrentMap generateConcurrentMap() { + static ConcurrentMap generateConcurrentMap() { return Maps.newConcurrentMap(); } @Generates - private static ConcurrentMap generateConcurrentMap(K key, V value) { + static ConcurrentMap generateConcurrentMap(K key, V value) { ConcurrentMap map = Maps.newConcurrentMap(); map.put(key, value); return map; } @Generates - private static , V> SortedMap generateSortedMap( - K key, V value) { + static , V> SortedMap generateSortedMap( + K key, @CheckForNull V value) { return generateNavigableMap(key, value); } @Generates - private static , V> NavigableMap generateNavigableMap( - K key, V value) { + static , V> NavigableMap generateNavigableMap( + K key, @CheckForNull V value) { return generateTreeMap(key, value); } @Generates - private static , V> TreeMap generateTreeMap( - K key, V value) { + static , V> TreeMap generateTreeMap( + K key, @CheckForNull V value) { TreeMap map = Maps.newTreeMap(); map.put(key, value); return map; } @Generates - private static , V> - ImmutableSortedMap generateImmutableSortedMap(K key, V value) { + static , V> ImmutableSortedMap generateImmutableSortedMap( + K key, V value) { return ImmutableSortedMap.of(key, value); } @Generates - private static Multimap generateMultimap(K key, V value) { + static Multimap generateMultimap(@CheckForNull K key, @CheckForNull V value) { return generateListMultimap(key, value); } @Generates - private static ImmutableMultimap generateImmutableMultimap(K key, V value) { + static ImmutableMultimap generateImmutableMultimap(K key, V value) { return ImmutableMultimap.of(key, value); } @Generates - private static ListMultimap generateListMultimap(K key, V value) { + static ListMultimap generateListMultimap( + @CheckForNull K key, @CheckForNull V value) { return generateArrayListMultimap(key, value); } @Generates - private static ArrayListMultimap generateArrayListMultimap(K key, V value) { + static ArrayListMultimap generateArrayListMultimap( + @CheckForNull K key, @CheckForNull V value) { ArrayListMultimap multimap = ArrayListMultimap.create(); multimap.put(key, value); return multimap; } @Generates - private static ImmutableListMultimap generateImmutableListMultimap(K key, V value) { + static ImmutableListMultimap generateImmutableListMultimap(K key, V value) { return ImmutableListMultimap.of(key, value); } @Generates - private static SetMultimap generateSetMultimap(K key, V value) { + static SetMultimap generateSetMultimap(@CheckForNull K key, @CheckForNull V value) { return generateLinkedHashMultimap(key, value); } @Generates - private static HashMultimap generateHashMultimap(K key, V value) { + static HashMultimap generateHashMultimap( + @CheckForNull K key, @CheckForNull V value) { HashMultimap multimap = HashMultimap.create(); multimap.put(key, value); return multimap; } @Generates - private static LinkedHashMultimap generateLinkedHashMultimap(K key, V value) { + static LinkedHashMultimap generateLinkedHashMultimap( + @CheckForNull K key, @CheckForNull V value) { LinkedHashMultimap multimap = LinkedHashMultimap.create(); multimap.put(key, value); return multimap; } @Generates - private static ImmutableSetMultimap generateImmutableSetMultimap(K key, V value) { + static ImmutableSetMultimap generateImmutableSetMultimap(K key, V value) { return ImmutableSetMultimap.of(key, value); } @Generates - private static BiMap generateBimap(K key, V value) { + static BiMap generateBimap(@CheckForNull K key, @CheckForNull V value) { return generateHashBiMap(key, value); } @Generates - private static HashBiMap generateHashBiMap(K key, V value) { + static HashBiMap generateHashBiMap(@CheckForNull K key, @CheckForNull V value) { HashBiMap bimap = HashBiMap.create(); bimap.put(key, value); return bimap; } @Generates - private static ImmutableBiMap generateImmutableBimap(K key, V value) { + static ImmutableBiMap generateImmutableBimap(K key, V value) { return ImmutableBiMap.of(key, value); } @Generates - private static Table generateTable(R row, C column, V value) { + static Table generateTable( + @CheckForNull R row, @CheckForNull C column, @CheckForNull V value) { return generateHashBasedTable(row, column, value); } @Generates - private static HashBasedTable generateHashBasedTable( - R row, C column, V value) { + static HashBasedTable generateHashBasedTable( + @CheckForNull R row, @CheckForNull C column, @CheckForNull V value) { HashBasedTable table = HashBasedTable.create(); table.put(row, column, value); return table; @@ -917,14 +921,14 @@ private static HashBasedTable generateHashBasedTable( @SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such @Generates - private static + static RowSortedTable generateRowSortedTable(R row, C column, V value) { return generateTreeBasedTable(row, column, value); } @SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such @Generates - private static + static TreeBasedTable generateTreeBasedTable(R row, C column, V value) { TreeBasedTable table = TreeBasedTable.create(); table.put(row, column, value); @@ -932,85 +936,84 @@ TreeBasedTable generateTreeBasedTable(R row, C column, V value) { } @Generates - private static ImmutableTable generateImmutableTable( - R row, C column, V value) { + static ImmutableTable generateImmutableTable(R row, C column, V value) { return ImmutableTable.of(row, column, value); } // common.reflect @Generates - private TypeToken generateTypeToken() { + TypeToken generateTypeToken() { return TypeToken.of(generateClass()); } // io types @Generates - private File generateFile() { + File generateFile() { return new File(generateString()); } @Generates - private static ByteArrayInputStream generateByteArrayInputStream() { + static ByteArrayInputStream generateByteArrayInputStream() { return new ByteArrayInputStream(new byte[0]); } @Generates - private static InputStream generateInputStream() { + static InputStream generateInputStream() { return generateByteArrayInputStream(); } @Generates - private StringReader generateStringReader() { + StringReader generateStringReader() { return new StringReader(generateString()); } @Generates - private Reader generateReader() { + Reader generateReader() { return generateStringReader(); } @Generates - private Readable generateReadable() { + Readable generateReadable() { return generateReader(); } @Generates - private Buffer generateBuffer() { + Buffer generateBuffer() { return generateCharBuffer(); } @Generates - private CharBuffer generateCharBuffer() { + CharBuffer generateCharBuffer() { return CharBuffer.allocate(generateInt()); } @Generates - private ByteBuffer generateByteBuffer() { + ByteBuffer generateByteBuffer() { return ByteBuffer.allocate(generateInt()); } @Generates - private ShortBuffer generateShortBuffer() { + ShortBuffer generateShortBuffer() { return ShortBuffer.allocate(generateInt()); } @Generates - private IntBuffer generateIntBuffer() { + IntBuffer generateIntBuffer() { return IntBuffer.allocate(generateInt()); } @Generates - private LongBuffer generateLongBuffer() { + LongBuffer generateLongBuffer() { return LongBuffer.allocate(generateInt()); } @Generates - private FloatBuffer generateFloatBuffer() { + FloatBuffer generateFloatBuffer() { return FloatBuffer.allocate(generateInt()); } @Generates - private DoubleBuffer generateDoubleBuffer() { + DoubleBuffer generateDoubleBuffer() { return DoubleBuffer.allocate(generateInt()); } } diff --git a/android/guava-testlib/src/com/google/common/testing/GcFinalization.java b/android/guava-testlib/src/com/google/common/testing/GcFinalization.java index 015afea54809..da6aa2211b49 100644 --- a/android/guava-testlib/src/com/google/common/testing/GcFinalization.java +++ b/android/guava-testlib/src/com/google/common/testing/GcFinalization.java @@ -18,7 +18,6 @@ import static java.util.concurrent.TimeUnit.SECONDS; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtIncompatible; import com.google.errorprone.annotations.DoNotMock; import com.google.j2objc.annotations.J2ObjCIncompatible; @@ -103,7 +102,6 @@ * @author Martin Buchholz * @since 11.0 */ -@Beta @GwtIncompatible @J2ObjCIncompatible // gc public final class GcFinalization { @@ -138,8 +136,8 @@ public static void awaitDone(Future future) { if (future.isDone()) { return; } - final long timeoutSeconds = timeoutSeconds(); - final long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds); + long timeoutSeconds = timeoutSeconds(); + long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds); do { System.runFinalization(); if (future.isDone()) { @@ -170,8 +168,8 @@ public static void awaitDone(FinalizationPredicate predicate) { if (predicate.isDone()) { return; } - final long timeoutSeconds = timeoutSeconds(); - final long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds); + long timeoutSeconds = timeoutSeconds(); + long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds); do { System.runFinalization(); if (predicate.isDone()) { @@ -198,8 +196,8 @@ public static void await(CountDownLatch latch) { if (latch.getCount() == 0) { return; } - final long timeoutSeconds = timeoutSeconds(); - final long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds); + long timeoutSeconds = timeoutSeconds(); + long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds); do { System.runFinalization(); if (latch.getCount() == 0) { @@ -222,13 +220,14 @@ public static void await(CountDownLatch latch) { * Creates a garbage object that counts down the latch in its finalizer. Sequestered into a * separate method to make it somewhat more likely to be unreachable. */ - private static void createUnreachableLatchFinalizer(final CountDownLatch latch) { - new Object() { - @Override - protected void finalize() { - latch.countDown(); - } - }; + private static void createUnreachableLatchFinalizer(CountDownLatch latch) { + Object unused = + new Object() { + @Override + protected void finalize() { + latch.countDown(); + } + }; } /** @@ -263,7 +262,7 @@ public interface FinalizationPredicate { * * @throws RuntimeException if timed out or interrupted while waiting */ - public static void awaitClear(final WeakReference ref) { + public static void awaitClear(WeakReference ref) { awaitDone( new FinalizationPredicate() { @Override @@ -296,9 +295,9 @@ public boolean isDone() { * @since 12.0 */ public static void awaitFullGc() { - final CountDownLatch finalizerRan = new CountDownLatch(1); + CountDownLatch finalizerRan = new CountDownLatch(1); WeakReference ref = - new WeakReference( + new WeakReference<>( new Object() { @Override protected void finalize() { diff --git a/android/guava-testlib/src/com/google/common/testing/NullPointerTester.java b/android/guava-testlib/src/com/google/common/testing/NullPointerTester.java index a32a53b7b050..4c24c65e17a4 100644 --- a/android/guava-testlib/src/com/google/common/testing/NullPointerTester.java +++ b/android/guava-testlib/src/com/google/common/testing/NullPointerTester.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Converter; import com.google.common.base.Objects; @@ -45,14 +44,14 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentMap; +import javax.annotation.CheckForNull; import junit.framework.Assert; import junit.framework.AssertionFailedError; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * A test utility that verifies that your methods and constructors throw {@link * NullPointerException} or {@link UnsupportedOperationException} whenever null is passed to a - * parameter that isn't annotated with an annotation with the simple name {@code Nullable}, {@lcode + * parameter that isn't annotated with an annotation with the simple name {@code Nullable}, {@code * CheckForNull}, {@link NullableType}, or {@link NullableDecl}. * *

    The tested methods and constructors are invoked -- each time with one parameter being null and @@ -66,7 +65,6 @@ * @author Kevin Bourrillion * @since 10.0 */ -@Beta @GwtIncompatible public final class NullPointerTester { @@ -176,7 +174,7 @@ public void testAllPublicInstanceMethods(Object instance) { * * @param instance the instance to invoke {@code method} on, or null if {@code method} is static */ - public void testMethod(@NullableDecl Object instance, Method method) { + public void testMethod(@CheckForNull Object instance, Method method) { Class[] types = method.getParameterTypes(); for (int nullIndex = 0; nullIndex < types.length; nullIndex++) { testMethodParameter(instance, method, nullIndex); @@ -208,7 +206,7 @@ public void testConstructor(Constructor ctor) { * @param instance the instance to invoke {@code method} on, or null if {@code method} is static */ public void testMethodParameter( - @NullableDecl final Object instance, final Method method, int paramIndex) { + @CheckForNull final Object instance, final Method method, int paramIndex) { method.setAccessible(true); testParameter(instance, invokable(instance, method), paramIndex, method.getDeclaringClass()); } @@ -461,7 +459,7 @@ R dummyReturnValue(TypeToken returnType) { }.newProxy(type); } - private static Invokable invokable(@NullableDecl Object instance, Method method) { + private static Invokable invokable(@CheckForNull Object instance, Method method) { if (instance == null) { return Invokable.from(method); } else { @@ -474,7 +472,8 @@ static boolean isPrimitiveOrNullable(Parameter param) { } private static final ImmutableSet NULLABLE_ANNOTATION_SIMPLE_NAMES = - ImmutableSet.of("CheckForNull", "Nullable", "NullableDecl", "NullableType"); + ImmutableSet.of( + "CheckForNull", "Nullable", "NullableDecl", "NullableType", "ParametricNullness"); static boolean isNullable(AnnotatedElement e) { for (Annotation annotation : e.getAnnotations()) { @@ -490,7 +489,7 @@ private boolean isIgnored(Member member) { } /** - * Returns true if the the given member is a method that overrides {@link Object#equals(Object)}. + * Returns true if the given member is a method that overrides {@link Object#equals(Object)}. * *

    The documentation for {@link Object#equals} says it should accept null, so don't require an * explicit {@code @NullableDecl} annotation (see item, Item other, bo } private Item getItem(int groupNumber, int itemNumber) { - return new Item(groups.get(groupNumber).get(itemNumber), groupNumber, itemNumber); + return new Item<>(groups.get(groupNumber).get(itemNumber), groupNumber, itemNumber); } static final class Item { diff --git a/android/guava-testlib/src/com/google/common/testing/SerializableTester.java b/android/guava-testlib/src/com/google/common/testing/SerializableTester.java index 62980764d65f..c4e6d236ee7e 100644 --- a/android/guava-testlib/src/com/google/common/testing/SerializableTester.java +++ b/android/guava-testlib/src/com/google/common/testing/SerializableTester.java @@ -16,7 +16,6 @@ package com.google.common.testing; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtCompatible; import junit.framework.Assert; import junit.framework.AssertionFailedError; @@ -32,7 +31,6 @@ * @author Mike Bostock * @since 10.0 */ -@Beta @GwtCompatible // but no-op! public final class SerializableTester { private SerializableTester() {} @@ -52,7 +50,6 @@ private SerializableTester() {} * @throws RuntimeException if the specified object was not successfully serialized or * deserialized */ - @SuppressWarnings("unchecked") public static T reserialize(T object) { return Platform.reserialize(object); } diff --git a/android/guava-testlib/src/com/google/common/testing/TestLogHandler.java b/android/guava-testlib/src/com/google/common/testing/TestLogHandler.java index c03093be52f3..263f8908ac36 100644 --- a/android/guava-testlib/src/com/google/common/testing/TestLogHandler.java +++ b/android/guava-testlib/src/com/google/common/testing/TestLogHandler.java @@ -16,14 +16,13 @@ package com.google.common.testing; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtCompatible; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Handler; import java.util.logging.LogRecord; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Tests may use this to intercept messages that are logged by the code under test. Example: @@ -52,7 +51,6 @@ * @author Kevin Bourrillion * @since 10.0 */ -@Beta @GwtCompatible public class TestLogHandler extends Handler { /** We will keep a private list of all logged records */ @@ -60,7 +58,7 @@ public class TestLogHandler extends Handler { /** Adds the most recently logged record to our list. */ @Override - public synchronized void publish(@NullableDecl LogRecord record) { + public synchronized void publish(@CheckForNull LogRecord record) { list.add(record); } diff --git a/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractListenableFutureTest.java b/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractListenableFutureTest.java index 2ba751537396..b5bec2c094bd 100644 --- a/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractListenableFutureTest.java +++ b/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractListenableFutureTest.java @@ -16,6 +16,9 @@ package com.google.common.util.concurrent.testing; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + import com.google.common.annotations.Beta; import com.google.common.annotations.GwtIncompatible; import com.google.common.util.concurrent.ListenableFuture; @@ -68,21 +71,18 @@ public void testGetBlocksUntilValueAvailable() throws Throwable { assertFalse(future.isDone()); assertFalse(future.isCancelled()); - final CountDownLatch successLatch = new CountDownLatch(1); - final Throwable[] badness = new Throwable[1]; + CountDownLatch successLatch = new CountDownLatch(1); + Throwable[] badness = new Throwable[1]; // Wait on the future in a separate thread. new Thread( - new Runnable() { - @Override - public void run() { - try { - assertSame(Boolean.TRUE, future.get()); - successLatch.countDown(); - } catch (Throwable t) { - t.printStackTrace(); - badness[0] = t; - } + () -> { + try { + assertSame(Boolean.TRUE, future.get()); + successLatch.countDown(); + } catch (Throwable t) { + t.printStackTrace(); + badness[0] = t; } }) .start(); @@ -90,7 +90,7 @@ public void run() { // Release the future value. latch.countDown(); - assertTrue(successLatch.await(10, TimeUnit.SECONDS)); + assertTrue(successLatch.await(10, SECONDS)); if (badness[0] != null) { throw badness[0]; @@ -105,7 +105,7 @@ public void testTimeoutOnGetWorksCorrectly() throws InterruptedException, Execut // The task thread waits for the latch, so we expect a timeout here. try { - future.get(20, TimeUnit.MILLISECONDS); + future.get(20, MILLISECONDS); fail("Should have timed out trying to get the value."); } catch (TimeoutException expected) { } finally { @@ -123,20 +123,17 @@ public void testCanceledFutureThrowsCancellation() throws Exception { assertFalse(future.isDone()); assertFalse(future.isCancelled()); - final CountDownLatch successLatch = new CountDownLatch(1); + CountDownLatch successLatch = new CountDownLatch(1); // Run cancellation in a separate thread as an extra thread-safety test. new Thread( - new Runnable() { - @Override - public void run() { - try { - future.get(); - } catch (CancellationException expected) { - successLatch.countDown(); - } catch (Exception ignored) { - // All other errors are ignored, we expect a cancellation. - } + () -> { + try { + future.get(); + } catch (CancellationException expected) { + successLatch.countDown(); + } catch (Exception ignored) { + // All other errors are ignored, we expect a cancellation. } }) .start(); @@ -149,37 +146,27 @@ public void run() { assertTrue(future.isDone()); assertTrue(future.isCancelled()); - assertTrue(successLatch.await(200, TimeUnit.MILLISECONDS)); + assertTrue(successLatch.await(200, MILLISECONDS)); latch.countDown(); } public void testListenersNotifiedOnError() throws Exception { - final CountDownLatch successLatch = new CountDownLatch(1); - final CountDownLatch listenerLatch = new CountDownLatch(1); + CountDownLatch successLatch = new CountDownLatch(1); + CountDownLatch listenerLatch = new CountDownLatch(1); ExecutorService exec = Executors.newCachedThreadPool(); - future.addListener( - new Runnable() { - @Override - public void run() { - listenerLatch.countDown(); - } - }, - exec); + future.addListener(listenerLatch::countDown, exec); new Thread( - new Runnable() { - @Override - public void run() { - try { - future.get(); - } catch (CancellationException expected) { - successLatch.countDown(); - } catch (Exception ignored) { - // No success latch count down. - } + () -> { + try { + future.get(); + } catch (CancellationException expected) { + successLatch.countDown(); + } catch (Exception ignored) { + // No success latch count down. } }) .start(); @@ -189,13 +176,13 @@ public void run() { assertTrue(future.isCancelled()); assertTrue(future.isDone()); - assertTrue(successLatch.await(200, TimeUnit.MILLISECONDS)); - assertTrue(listenerLatch.await(200, TimeUnit.MILLISECONDS)); + assertTrue(successLatch.await(200, MILLISECONDS)); + assertTrue(listenerLatch.await(200, MILLISECONDS)); latch.countDown(); exec.shutdown(); - exec.awaitTermination(100, TimeUnit.MILLISECONDS); + exec.awaitTermination(100, MILLISECONDS); } /** @@ -209,7 +196,7 @@ public void testAllListenersCompleteSuccessfully() ExecutorService exec = Executors.newCachedThreadPool(); int listenerCount = 20; - final CountDownLatch listenerLatch = new CountDownLatch(listenerCount); + CountDownLatch listenerLatch = new CountDownLatch(listenerCount); // Test that listeners added both before and after the value is available // get called correctly. @@ -217,31 +204,17 @@ public void testAllListenersCompleteSuccessfully() // Right in the middle start up a thread to close the latch. if (i == 10) { - new Thread( - new Runnable() { - @Override - public void run() { - latch.countDown(); - } - }) - .start(); + new Thread(() -> latch.countDown()).start(); } - future.addListener( - new Runnable() { - @Override - public void run() { - listenerLatch.countDown(); - } - }, - exec); + future.addListener(listenerLatch::countDown, exec); } assertSame(Boolean.TRUE, future.get()); // Wait for the listener latch to complete. - listenerLatch.await(500, TimeUnit.MILLISECONDS); + listenerLatch.await(500, MILLISECONDS); exec.shutdown(); - exec.awaitTermination(500, TimeUnit.MILLISECONDS); + exec.awaitTermination(500, MILLISECONDS); } } diff --git a/android/guava-testlib/src/com/google/common/util/concurrent/testing/MockFutureListener.java b/android/guava-testlib/src/com/google/common/util/concurrent/testing/MockFutureListener.java index fc3ed21f1ba9..a2fe4f447a79 100644 --- a/android/guava-testlib/src/com/google/common/util/concurrent/testing/MockFutureListener.java +++ b/android/guava-testlib/src/com/google/common/util/concurrent/testing/MockFutureListener.java @@ -17,13 +17,13 @@ package com.google.common.util.concurrent.testing; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; +import static java.util.concurrent.TimeUnit.SECONDS; import com.google.common.annotations.Beta; import com.google.common.annotations.GwtIncompatible; import com.google.common.util.concurrent.ListenableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; import junit.framework.Assert; /** @@ -59,7 +59,7 @@ public void run() { */ public void assertSuccess(Object expectedData) throws Throwable { // Verify that the listener executed in a reasonable amount of time. - Assert.assertTrue(countDownLatch.await(1L, TimeUnit.SECONDS)); + Assert.assertTrue(countDownLatch.await(1L, SECONDS)); try { Assert.assertEquals(expectedData, future.get()); @@ -75,7 +75,7 @@ public void assertSuccess(Object expectedData) throws Throwable { */ public void assertException(Throwable expectedCause) throws Exception { // Verify that the listener executed in a reasonable amount of time. - Assert.assertTrue(countDownLatch.await(1L, TimeUnit.SECONDS)); + Assert.assertTrue(countDownLatch.await(1L, SECONDS)); try { future.get(); @@ -88,6 +88,6 @@ public void assertException(Throwable expectedCause) throws Exception { public void assertTimeout() throws Exception { // Verify that the listener does not get called in a reasonable amount of // time. - Assert.assertFalse(countDownLatch.await(1L, TimeUnit.SECONDS)); + Assert.assertFalse(countDownLatch.await(1L, SECONDS)); } } diff --git a/android/guava-testlib/src/com/google/common/util/concurrent/testing/SameThreadScheduledExecutorService.java b/android/guava-testlib/src/com/google/common/util/concurrent/testing/SameThreadScheduledExecutorService.java index c232218fb4bf..25b7ef791c00 100644 --- a/android/guava-testlib/src/com/google/common/util/concurrent/testing/SameThreadScheduledExecutorService.java +++ b/android/guava-testlib/src/com/google/common/util/concurrent/testing/SameThreadScheduledExecutorService.java @@ -140,11 +140,11 @@ public ListenableScheduledFuture schedule(Runnable command, long delay, TimeU @Override public ListenableScheduledFuture schedule( - final Callable callable, long delay, TimeUnit unit) { + Callable callable, long delay, TimeUnit unit) { Preconditions.checkNotNull(callable, "callable must not be null!"); Preconditions.checkNotNull(unit, "unit must not be null!"); ListenableFuture delegateFuture = submit(callable); - return new ImmediateScheduledFuture(delegateFuture); + return new ImmediateScheduledFuture<>(delegateFuture); } private static class ImmediateScheduledFuture extends SimpleForwardingListenableFuture diff --git a/android/guava-testlib/src/com/google/common/util/concurrent/testing/TestingExecutors.java b/android/guava-testlib/src/com/google/common/util/concurrent/testing/TestingExecutors.java index 421243043245..dc2c40d37492 100644 --- a/android/guava-testlib/src/com/google/common/util/concurrent/testing/TestingExecutors.java +++ b/android/guava-testlib/src/com/google/common/util/concurrent/testing/TestingExecutors.java @@ -16,6 +16,8 @@ package com.google.common.util.concurrent.testing; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + import com.google.common.annotations.Beta; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.ImmutableList; @@ -153,7 +155,7 @@ private static class NeverScheduledFuture extends AbstractFuture implements ListenableScheduledFuture { static NeverScheduledFuture create() { - return new NeverScheduledFuture(); + return new NeverScheduledFuture<>(); } @Override @@ -163,7 +165,7 @@ public long getDelay(TimeUnit unit) { @Override public int compareTo(Delayed other) { - return Longs.compare(getDelay(TimeUnit.NANOSECONDS), other.getDelay(TimeUnit.NANOSECONDS)); + return Longs.compare(getDelay(NANOSECONDS), other.getDelay(NANOSECONDS)); } } } diff --git a/android/guava-testlib/test/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilderTest.java b/android/guava-testlib/test/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilderTest.java index dc0fe37b4471..4d617d64db09 100644 --- a/android/guava-testlib/test/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilderTest.java +++ b/android/guava-testlib/test/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilderTest.java @@ -27,7 +27,7 @@ /** @author Max Ross */ public class FeatureSpecificTestSuiteBuilderTest extends TestCase { - static boolean testWasRun; + private static boolean testWasRun; @Override protected void setUp() throws Exception { @@ -52,7 +52,7 @@ protected List> getTesters() { } public void testLifecycle() { - final boolean setUp[] = {false}; + boolean[] setUp = {false}; Runnable setUpRunnable = new Runnable() { @Override @@ -61,7 +61,7 @@ public void run() { } }; - final boolean tearDown[] = {false}; + boolean[] tearDown = {false}; Runnable tearDownRunnable = new Runnable() { @Override diff --git a/android/guava-testlib/test/com/google/common/collect/testing/MapTestSuiteBuilderTests.java b/android/guava-testlib/test/com/google/common/collect/testing/MapTestSuiteBuilderTests.java index 1a54f6862ded..a4d216d1503c 100644 --- a/android/guava-testlib/test/com/google/common/collect/testing/MapTestSuiteBuilderTests.java +++ b/android/guava-testlib/test/com/google/common/collect/testing/MapTestSuiteBuilderTests.java @@ -26,6 +26,11 @@ import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.Feature; import com.google.common.collect.testing.features.MapFeature; +import com.google.common.reflect.Reflection; +import java.io.Serializable; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.Collection; @@ -36,6 +41,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; @@ -52,6 +58,7 @@ public static Test suite() { TestSuite suite = new TestSuite(MapTestSuiteBuilderTests.class.getSimpleName()); suite.addTest(testsForHashMapNullKeysForbidden()); suite.addTest(testsForHashMapNullValuesForbidden()); + suite.addTest(testsForSetUpTearDown()); return suite; } @@ -252,4 +259,89 @@ public String put(String key, String value) { "HashMap w/out null values", ALLOWS_NULL_KEYS); } + + /** + * Map generator that verifies that {@code setUp()} methods are called in all the test cases. The + * {@code setUpRan} parameter is set true by the {@code setUp} that every test case is supposed to + * have registered, and set false by the {@code tearDown}. We use a dynamic proxy to intercept all + * of the {@code Map} method calls and check that {@code setUpRan} is true. + */ + private static class CheckSetUpHashMapGenerator extends WrappedHashMapGenerator { + private final AtomicBoolean setUpRan; + + CheckSetUpHashMapGenerator(AtomicBoolean setUpRan) { + this.setUpRan = setUpRan; + } + + @Override + Map wrap(HashMap map) { + @SuppressWarnings("unchecked") + Map proxy = + Reflection.newProxy(Map.class, new CheckSetUpInvocationHandler(map, setUpRan)); + return proxy; + } + } + + /** + * Intercepts calls to a {@code Map} to check that {@code setUpRan} is true when they happen. Then + * forwards the calls to the underlying {@code Map}. + */ + private static class CheckSetUpInvocationHandler implements InvocationHandler, Serializable { + private final Map map; + private final AtomicBoolean setUpRan; + + CheckSetUpInvocationHandler(Map map, AtomicBoolean setUpRan) { + this.map = map; + this.setUpRan = setUpRan; + } + + @Override + public Object invoke(Object target, Method method, Object[] args) throws Throwable { + assertTrue("setUp should have run", setUpRan.get()); + try { + return method.invoke(map, args); + } catch (InvocationTargetException e) { + throw e.getCause(); + } catch (IllegalAccessException e) { + throw newLinkageError(e); + } + } + } + + /** Verifies that {@code setUp} and {@code tearDown} are called in all map test cases. */ + private static Test testsForSetUpTearDown() { + final AtomicBoolean setUpRan = new AtomicBoolean(); + Runnable setUp = + new Runnable() { + @Override + public void run() { + assertFalse("previous tearDown should have run before setUp", setUpRan.getAndSet(true)); + } + }; + Runnable tearDown = + new Runnable() { + @Override + public void run() { + assertTrue("setUp should have run", setUpRan.getAndSet(false)); + } + }; + return MapTestSuiteBuilder.using(new CheckSetUpHashMapGenerator(setUpRan)) + .named("setUpTearDown") + .withFeatures( + MapFeature.GENERAL_PURPOSE, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_NULL_VALUES, + CollectionFeature.SERIALIZABLE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, + CollectionSize.ANY) + .withSetUp(setUp) + .withTearDown(tearDown) + .createTestSuite(); + } + + private static LinkageError newLinkageError(Throwable cause) { + LinkageError error = new LinkageError(cause.toString()); + error.initCause(cause); + return error; + } } diff --git a/android/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java b/android/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java index 586eb284eb91..be1752d4793a 100644 --- a/android/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java +++ b/android/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java @@ -34,9 +34,9 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; +import javax.annotation.CheckForNull; import junit.framework.AssertionFailedError; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Unit tests for {@link ClassSanityTester}. @@ -58,7 +58,7 @@ public static Object good( // oneConstantOnly doesn't matter since it's not nullable and can be only 1 value. @SuppressWarnings("unused") OneConstantEnum oneConstantOnly, // noConstant doesn't matter since it can only be null - @SuppressWarnings("unused") @NullableDecl NoConstantEnum noConstant) { + @SuppressWarnings("unused") @CheckForNull NoConstantEnum noConstant) { return new GoodEquals(a, b); } // instance method ignored @@ -106,7 +106,7 @@ public void testEqualsOnReturnValues_bad() throws Exception { private static class BadEqualsFactory { /** oneConstantOnly matters now since it can be either null or the constant. */ @SuppressWarnings("unused") // Called by reflection - public static Object bad(String a, int b, @NullableDecl OneConstantEnum oneConstantOnly) { + public static Object bad(String a, int b, @CheckForNull OneConstantEnum oneConstantOnly) { return new GoodEquals(a, b); } } @@ -287,7 +287,7 @@ public void testEqualsAndSerializableForReturnValues_factoryReturnsNullAndAnnota } public static class FactoryThatReturnsNullAndAnnotated { - @NullableDecl + @CheckForNull public static Object bad() { return null; } @@ -616,7 +616,7 @@ public HasAnInterface(AnInterface i) { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof HasAnInterface) { HasAnInterface that = (HasAnInterface) obj; return i.equals(that.i); @@ -673,7 +673,7 @@ private abstract static class Wrapper { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { // In general getClass().isInstance() is bad for equals. // But here we fully control the subclasses to ensure symmetry. if (getClass().isInstance(obj)) { @@ -753,13 +753,13 @@ static GoodEquals create(String a, int b) { // keep trying @SuppressWarnings("unused") - @NullableDecl + @CheckForNull public static GoodEquals createMayReturnNull(int a, int b) { return null; } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof GoodEquals) { GoodEquals that = (GoodEquals) obj; return a.equals(that.a) && b == that.b; @@ -778,12 +778,12 @@ static class BadEquals { public BadEquals() {} // ignored by testEquals() since it has less parameters. - public static BadEquals create(@SuppressWarnings("unused") @NullableDecl String s) { + public static BadEquals create(@SuppressWarnings("unused") @CheckForNull String s) { return new BadEquals(); } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { return obj instanceof BadEquals; } @@ -1122,7 +1122,7 @@ public static BadEqualsWithParameterizedType create( } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { return obj instanceof BadEqualsWithParameterizedType; } @@ -1156,12 +1156,12 @@ public NoNullCheckNeededDespitNotInstantiable(NotInstantiable x) { void primitiveOnly(int i) {} @SuppressWarnings("unused") // reflected - void nullableOnly(@NullableDecl String s) {} + void nullableOnly(@CheckForNull String s) {} public void noParameter() {} @SuppressWarnings("unused") // reflected - void primitiveAndNullable(@NullableDecl String s, int i) {} + void primitiveAndNullable(@CheckForNull String s, int i) {} } static class FactoryMethodReturnsNullButNotAnnotated { @@ -1175,7 +1175,7 @@ static FactoryMethodReturnsNullButNotAnnotated returnsNull() { static class FactoryMethodReturnsNullAndAnnotated { private FactoryMethodReturnsNullAndAnnotated() {} - @NullableDecl + @CheckForNull public static FactoryMethodReturnsNullAndAnnotated returnsNull() { return null; } @@ -1189,7 +1189,7 @@ private FactoryMethodAcceptsNull(String name) { this.name = name; } - static FactoryMethodAcceptsNull create(@NullableDecl String name) { + static FactoryMethodAcceptsNull create(@CheckForNull String name) { return new FactoryMethodAcceptsNull(name); } } @@ -1211,7 +1211,7 @@ static class ConstructorAcceptsNull { final String name; - public ConstructorAcceptsNull(@NullableDecl String name) { + public ConstructorAcceptsNull(@CheckForNull String name) { this.name = name; } } @@ -1237,7 +1237,7 @@ public ConstructorParameterMapOfNotInstantiable(Map } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { throw new UnsupportedOperationException(); } diff --git a/android/guava-testlib/test/com/google/common/testing/EquivalenceTesterTest.java b/android/guava-testlib/test/com/google/common/testing/EquivalenceTesterTest.java index d612b2c2c876..865c198e727f 100644 --- a/android/guava-testlib/test/com/google/common/testing/EquivalenceTesterTest.java +++ b/android/guava-testlib/test/com/google/common/testing/EquivalenceTesterTest.java @@ -237,7 +237,7 @@ void expectHash(Object object, int hash) { void replay() { checkRecording(); equivalentExpectations = equivalentExpectationsBuilder.build(); - hashExpectations = hashExpectationsBuilder.build(); + hashExpectations = hashExpectationsBuilder.buildOrThrow(); } @Override diff --git a/android/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java b/android/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java index d1dc49bf165b..218edef0a632 100644 --- a/android/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java +++ b/android/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java @@ -44,9 +44,9 @@ import java.util.Map; import java.util.Set; import java.util.SortedSet; +import javax.annotation.CheckForNull; import junit.framework.AssertionFailedError; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Unit test for {@link NullPointerTester}. @@ -86,11 +86,11 @@ public static void staticOneArgCheckForNullCorrectlyDoesNotThrowNPE( // null? no problem } - public static void staticOneArgJsr305NullableCorrectlyDoesNotThrowNPE(@NullableDecl String s) { + public static void staticOneArgJsr305NullableCorrectlyDoesNotThrowNPE(@CheckForNull String s) { // null? no problem } - public static void staticOneArgNullableCorrectlyDoesNotThrowNPE(@NullableDecl String s) { + public static void staticOneArgNullableCorrectlyDoesNotThrowNPE(@CheckForNull String s) { // null? no problem } @@ -99,7 +99,7 @@ public static void staticOneArgCheckForNullCorrectlyThrowsOtherThanNPE( throw new FooException(); // ok, as long as it's not NullPointerException } - public static void staticOneArgNullableCorrectlyThrowsOtherThanNPE(@NullableDecl String s) { + public static void staticOneArgNullableCorrectlyThrowsOtherThanNPE(@CheckForNull String s) { throw new FooException(); // ok, as long as it's not NullPointerException } @@ -107,7 +107,7 @@ public static void staticOneArgCheckForNullThrowsNPE(@javax.annotation.CheckForN checkNotNull(s); // doesn't check if you said you'd accept null, but you don't } - public static void staticOneArgNullableThrowsNPE(@NullableDecl String s) { + public static void staticOneArgNullableThrowsNPE(@CheckForNull String s) { checkNotNull(s); // doesn't check if you said you'd accept null, but you don't } @@ -128,7 +128,7 @@ public void oneArgCheckForNullCorrectlyDoesNotThrowNPE( // null? no problem } - public void oneArgNullableCorrectlyDoesNotThrowNPE(@NullableDecl String s) { + public void oneArgNullableCorrectlyDoesNotThrowNPE(@CheckForNull String s) { // null? no problem } @@ -137,7 +137,7 @@ public void oneArgCheckForNullCorrectlyThrowsOtherThanNPE( throw new FooException(); // ok, as long as it's not NullPointerException } - public void oneArgNullableCorrectlyThrowsOtherThanNPE(@NullableDecl String s) { + public void oneArgNullableCorrectlyThrowsOtherThanNPE(@CheckForNull String s) { throw new FooException(); // ok, as long as it's not NullPointerException } @@ -145,7 +145,7 @@ public void oneArgCheckForNullThrowsNPE(@javax.annotation.CheckForNull String s) checkNotNull(s); // doesn't check if you said you'd accept null, but you don't } - public void oneArgNullableThrowsNPE(@NullableDecl String s) { + public void oneArgNullableThrowsNPE(@CheckForNull String s) { checkNotNull(s); // doesn't check if you said you'd accept null, but you don't } } @@ -347,19 +347,19 @@ public void normalNormal(String first, Integer second) { /** Two-arg method with the second param Nullable. */ @SuppressWarnings("GoodTime") // false positive; b/122617528 - public void normalNullable(String first, @NullableDecl Integer second) { + public void normalNullable(String first, @CheckForNull Integer second) { reactToNullParameters(first, second); } /** Two-arg method with the first param Nullable. */ @SuppressWarnings("GoodTime") // false positive; b/122617528 - public void nullableNormal(@NullableDecl String first, Integer second) { + public void nullableNormal(@CheckForNull String first, Integer second) { reactToNullParameters(first, second); } /** Two-arg method with the both params Nullable. */ @SuppressWarnings("GoodTime") // false positive; b/122617528 - public void nullableNullable(@NullableDecl String first, @NullableDecl Integer second) { + public void nullableNullable(@CheckForNull String first, @CheckForNull Integer second) { reactToNullParameters(first, second); } @@ -473,9 +473,9 @@ protected void protectedOneArg(String s) { checkNotNull(s); } - public void oneNullableArg(@NullableDecl String s) {} + public void oneNullableArg(@CheckForNull String s) {} - public void oneNullableArgThrows(@NullableDecl String s) { + public void oneNullableArgThrows(@CheckForNull String s) { doThrow(s); } @@ -484,31 +484,31 @@ public void twoArg(String s, Integer i) { i.intValue(); } - public void twoMixedArgs(String s, @NullableDecl Integer i) { + public void twoMixedArgs(String s, @CheckForNull Integer i) { checkNotNull(s); } - public void twoMixedArgs(@NullableDecl Integer i, String s) { + public void twoMixedArgs(@CheckForNull Integer i, String s) { checkNotNull(s); } - public void twoMixedArgsThrows(String s, @NullableDecl Integer i) { + public void twoMixedArgsThrows(String s, @CheckForNull Integer i) { checkNotNull(s); doThrow(i); } - public void twoMixedArgsThrows(@NullableDecl Integer i, String s) { + public void twoMixedArgsThrows(@CheckForNull Integer i, String s) { checkNotNull(s); doThrow(i); } - public void twoNullableArgs(@NullableDecl String s, @NullableDecl Integer i) {} + public void twoNullableArgs(@CheckForNull String s, @CheckForNull Integer i) {} - public void twoNullableArgsThrowsFirstArg(@NullableDecl String s, @NullableDecl Integer i) { + public void twoNullableArgsThrowsFirstArg(@CheckForNull String s, @CheckForNull Integer i) { doThrow(s); } - public void twoNullableArgsThrowsSecondArg(@NullableDecl String s, @NullableDecl Integer i) { + public void twoNullableArgsThrowsSecondArg(@CheckForNull String s, @CheckForNull Integer i) { doThrow(i); } @@ -516,9 +516,9 @@ public static void staticOneArg(String s) { checkNotNull(s); } - public static void staticOneNullableArg(@NullableDecl String s) {} + public static void staticOneNullableArg(@CheckForNull String s) {} - public static void staticOneNullableArgThrows(@NullableDecl String s) { + public static void staticOneNullableArgThrows(@CheckForNull String s) { doThrow(s); } } @@ -551,7 +551,7 @@ public void testFailOneArgThrowsWrongType() { private static class PassOneNullableArgThrowsNPE extends PassObject { @Override - public void oneNullableArg(@NullableDecl String s) { + public void oneNullableArg(@CheckForNull String s) { checkNotNull(s); // ok to throw NPE } } @@ -610,7 +610,7 @@ public void testFailTwoArgsSecondArgThrowsWrongType() { private static class FailTwoMixedArgsFirstArgDoesntThrowNPE extends PassObject { @Override - public void twoMixedArgs(String s, @NullableDecl Integer i) { + public void twoMixedArgs(String s, @CheckForNull Integer i) { // Fail: missing NPE for s } } @@ -621,7 +621,7 @@ public void testFailTwoMixedArgsFirstArgDoesntThrowNPE() { private static class FailTwoMixedArgsFirstArgThrowsWrongType extends PassObject { @Override - public void twoMixedArgs(String s, @NullableDecl Integer i) { + public void twoMixedArgs(String s, @CheckForNull Integer i) { doThrow(s); // Fail: throwing non-NPE exception for null s } } @@ -632,7 +632,7 @@ public void testFailTwoMixedArgsFirstArgThrowsWrongType() { private static class PassTwoMixedArgsNullableArgThrowsNPE extends PassObject { @Override - public void twoMixedArgs(String s, @NullableDecl Integer i) { + public void twoMixedArgs(String s, @CheckForNull Integer i) { checkNotNull(s); i.intValue(); // ok to throw NPE? } @@ -644,7 +644,7 @@ public void testPassTwoMixedArgsNullableArgThrowsNPE() { private static class PassTwoMixedArgSecondNullableArgThrowsOther extends PassObject { @Override - public void twoMixedArgs(String s, @NullableDecl Integer i) { + public void twoMixedArgs(String s, @CheckForNull Integer i) { checkNotNull(s); doThrow(i); // ok to throw non-NPE exception for null i } @@ -656,7 +656,7 @@ public void testPassTwoMixedArgSecondNullableArgThrowsOther() { private static class FailTwoMixedArgsSecondArgDoesntThrowNPE extends PassObject { @Override - public void twoMixedArgs(@NullableDecl Integer i, String s) { + public void twoMixedArgs(@CheckForNull Integer i, String s) { // Fail: missing NPE for null s } } @@ -667,7 +667,7 @@ public void testFailTwoMixedArgsSecondArgDoesntThrowNPE() { private static class FailTwoMixedArgsSecondArgThrowsWrongType extends PassObject { @Override - public void twoMixedArgs(@NullableDecl Integer i, String s) { + public void twoMixedArgs(@CheckForNull Integer i, String s) { doThrow(s); // Fail: throwing non-NPE exception for null s } } @@ -678,7 +678,7 @@ public void testFailTwoMixedArgsSecondArgThrowsWrongType() { private static class PassTwoNullableArgsFirstThrowsNPE extends PassObject { @Override - public void twoNullableArgs(@NullableDecl String s, @NullableDecl Integer i) { + public void twoNullableArgs(@CheckForNull String s, @CheckForNull Integer i) { checkNotNull(s); // ok to throw NPE? } } @@ -689,7 +689,7 @@ public void testPassTwoNullableArgsFirstThrowsNPE() { private static class PassTwoNullableArgsFirstThrowsOther extends PassObject { @Override - public void twoNullableArgs(@NullableDecl String s, @NullableDecl Integer i) { + public void twoNullableArgs(@CheckForNull String s, @CheckForNull Integer i) { doThrow(s); // ok to throw non-NPE exception for null s } } @@ -700,7 +700,7 @@ public void testPassTwoNullableArgsFirstThrowsOther() { private static class PassTwoNullableArgsSecondThrowsNPE extends PassObject { @Override - public void twoNullableArgs(@NullableDecl String s, @NullableDecl Integer i) { + public void twoNullableArgs(@CheckForNull String s, @CheckForNull Integer i) { i.intValue(); // ok to throw NPE? } } @@ -711,7 +711,7 @@ public void testPassTwoNullableArgsSecondThrowsNPE() { private static class PassTwoNullableArgsSecondThrowsOther extends PassObject { @Override - public void twoNullableArgs(@NullableDecl String s, @NullableDecl Integer i) { + public void twoNullableArgs(@CheckForNull String s, @CheckForNull Integer i) { doThrow(i); // ok to throw non-NPE exception for null i } } @@ -722,7 +722,7 @@ public void testPassTwoNullableArgsSecondThrowsOther() { private static class PassTwoNullableArgsNeitherThrowsAnything extends PassObject { @Override - public void twoNullableArgs(@NullableDecl String s, @NullableDecl Integer i) { + public void twoNullableArgs(@CheckForNull String s, @CheckForNull Integer i) { // ok to do nothing } } @@ -768,7 +768,7 @@ public void testSubclassWithBadSuperclassForPackageProtectedMethod() { private static class SubclassThatOverridesBadSuperclassMethod extends BaseClassThatFailsToThrow { @Override - public void oneArg(@NullableDecl String s) {} + public void oneArg(@CheckForNull String s) {} } public void testSubclassThatOverridesBadSuperclassMethod() { @@ -777,7 +777,7 @@ public void testSubclassThatOverridesBadSuperclassMethod() { @SuppressWarnings("unused") // for NullPointerTester private static class SubclassOverridesTheWrongMethod extends BaseClassThatFailsToThrow { - public void oneArg(@NullableDecl CharSequence s) {} + public void oneArg(@CheckForNull CharSequence s) {} } public void testSubclassOverridesTheWrongMethod() { @@ -801,7 +801,7 @@ public void testSubclassThatFailsToThrowForStatic() { private static class SubclassThatTriesToOverrideBadStaticMethod extends ClassThatFailsToThrowForStatic { - static void staticOneArg(@NullableDecl String s) {} + static void staticOneArg(@CheckForNull String s) {} } public void testSubclassThatTriesToOverrideBadStaticMethod() { @@ -814,7 +814,7 @@ private HardToCreate(HardToCreate x) {} @SuppressWarnings("unused") // used by reflection private static class CanCreateDefault { - public void foo(@NullableDecl HardToCreate ignored, String required) { + public void foo(@CheckForNull HardToCreate ignored, String required) { checkNotNull(required); } } @@ -877,7 +877,7 @@ private static void shouldFail(Class cls) { @SuppressWarnings("unused") // used by reflection private static class PrivateClassWithPrivateConstructor { - private PrivateClassWithPrivateConstructor(@NullableDecl Integer argument) {} + private PrivateClassWithPrivateConstructor(@CheckForNull Integer argument) {} } public void testPrivateClass() { diff --git a/android/guava-tests/benchmark/com/google/common/base/StringsRepeatBenchmark.java b/android/guava-tests/benchmark/com/google/common/base/StringsRepeatBenchmark.java index 30261da5d8ff..16e00ef3d2e2 100644 --- a/android/guava-tests/benchmark/com/google/common/base/StringsRepeatBenchmark.java +++ b/android/guava-tests/benchmark/com/google/common/base/StringsRepeatBenchmark.java @@ -40,7 +40,7 @@ void setUp() { } @Benchmark - void oldRepeat(int reps) { + void oldRepeat(long reps) { for (int i = 0; i < reps; i++) { String x = oldRepeat(originalString, count); if (x.length() != (originalString.length() * count)) { @@ -62,7 +62,7 @@ private static String oldRepeat(String string, int count) { } @Benchmark - void mikeRepeat(int reps) { + void mikeRepeat(long reps) { for (int i = 0; i < reps; i++) { String x = mikeRepeat(originalString, count); if (x.length() != (originalString.length() * count)) { @@ -95,7 +95,7 @@ private static String mikeRepeat(String string, int count) { } @Benchmark - void martinRepeat(int reps) { + void martinRepeat(long reps) { for (int i = 0; i < reps; i++) { String x = martinRepeat(originalString, count); if (x.length() != (originalString.length() * count)) { diff --git a/android/guava-tests/benchmark/com/google/common/base/ToStringHelperBenchmark.java b/android/guava-tests/benchmark/com/google/common/base/ToStringHelperBenchmark.java index 2d7a447272b1..47dd8f46a154 100644 --- a/android/guava-tests/benchmark/com/google/common/base/ToStringHelperBenchmark.java +++ b/android/guava-tests/benchmark/com/google/common/base/ToStringHelperBenchmark.java @@ -136,4 +136,6 @@ int toString(int reps) { } return dummy; } + + // When omitEmptyValues() is released, remove this method and add a new @Param "omitEmptyValues". } diff --git a/android/guava-tests/benchmark/com/google/common/collect/ConcurrentHashMultisetBenchmark.java b/android/guava-tests/benchmark/com/google/common/collect/ConcurrentHashMultisetBenchmark.java index 5b713f26b64f..086a634932f3 100644 --- a/android/guava-tests/benchmark/com/google/common/collect/ConcurrentHashMultisetBenchmark.java +++ b/android/guava-tests/benchmark/com/google/common/collect/ConcurrentHashMultisetBenchmark.java @@ -37,7 +37,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Benchmarks for {@link ConcurrentHashMultiset}. @@ -192,7 +192,7 @@ public static OldConcurrentHashMultiset create() { * @return the nonnegative number of occurrences of the element */ @Override - public int count(@NullableDecl Object element) { + public int count(@CheckForNull Object element) { try { return unbox(countMap.get(element)); } catch (NullPointerException | ClassCastException e) { @@ -295,7 +295,7 @@ public int add(E element, int occurrences) { * @throws IllegalArgumentException if {@code occurrences} is negative */ @Override - public int remove(@NullableDecl Object element, int occurrences) { + public int remove(@CheckForNull Object element, int occurrences) { if (occurrences == 0) { return count(element); } @@ -330,7 +330,7 @@ public int remove(@NullableDecl Object element, int occurrences) { * @param element the element whose occurrences should all be removed * @return the number of occurrences successfully removed, possibly zero */ - private int removeAllOccurrences(@NullableDecl Object element) { + private int removeAllOccurrences(@CheckForNull Object element) { try { return unbox(countMap.remove(element)); } catch (NullPointerException | ClassCastException e) { @@ -349,7 +349,7 @@ private int removeAllOccurrences(@NullableDecl Object element) { * @param occurrences the number of occurrences of {@code element} to remove * @return {@code true} if the removal was possible (including if {@code occurrences} is zero) */ - public boolean removeExactly(@NullableDecl Object element, int occurrences) { + public boolean removeExactly(@CheckForNull Object element, int occurrences) { if (occurrences == 0) { return true; } @@ -543,7 +543,7 @@ public int hashCode() { } /** We use a special form of unboxing that treats null as zero. */ - private static int unbox(@NullableDecl Integer i) { + private static int unbox(@CheckForNull Integer i) { return (i == null) ? 0 : i; } } diff --git a/android/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java b/android/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java index f10b94ea6e10..cd8e24b1ef76 100644 --- a/android/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java +++ b/android/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java @@ -139,7 +139,7 @@ Map create(Collection keys) { for (Element element : keys) { builder.put(element, element); } - return builder.build(); + return builder.buildOrThrow(); } }, ImmutableSorted { diff --git a/android/guava-tests/benchmark/com/google/common/util/concurrent/ExecutionListBenchmark.java b/android/guava-tests/benchmark/com/google/common/util/concurrent/ExecutionListBenchmark.java index c9df7748336e..22053c8d696a 100644 --- a/android/guava-tests/benchmark/com/google/common/util/concurrent/ExecutionListBenchmark.java +++ b/android/guava-tests/benchmark/com/google/common/util/concurrent/ExecutionListBenchmark.java @@ -38,7 +38,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** Benchmarks for {@link ExecutionList}. */ @VmOptions({"-Xms8g", "-Xmx8g"}) @@ -488,7 +488,7 @@ private static void executeListener(Runnable runnable, Executor executor) { private static final class RunnableExecutorPair { final Runnable runnable; final Executor executor; - @NullableDecl RunnableExecutorPair next; + @CheckForNull RunnableExecutorPair next; RunnableExecutorPair(Runnable runnable, Executor executor, RunnableExecutorPair next) { this.runnable = runnable; @@ -563,7 +563,7 @@ private static void executeListener(Runnable runnable, Executor executor) { private static final class RunnableExecutorPair { Runnable runnable; Executor executor; - @NullableDecl RunnableExecutorPair next; + @CheckForNull RunnableExecutorPair next; RunnableExecutorPair(Runnable runnable, Executor executor) { this.runnable = runnable; @@ -669,7 +669,7 @@ private static class RunnableExecutorPair { final Runnable runnable; final Executor executor; // Volatile because this is written on one thread and read on another with no synchronization. - @NullableDecl volatile RunnableExecutorPair next; + @CheckForNull volatile RunnableExecutorPair next; RunnableExecutorPair(Runnable runnable, Executor executor) { this.runnable = runnable; diff --git a/android/guava-tests/benchmark/com/google/common/util/concurrent/FuturesGetCheckedBenchmark.java b/android/guava-tests/benchmark/com/google/common/util/concurrent/FuturesGetCheckedBenchmark.java index dd1883bcb053..9129bfc2a9f1 100644 --- a/android/guava-tests/benchmark/com/google/common/util/concurrent/FuturesGetCheckedBenchmark.java +++ b/android/guava-tests/benchmark/com/google/common/util/concurrent/FuturesGetCheckedBenchmark.java @@ -21,7 +21,6 @@ import static com.google.common.util.concurrent.Futures.immediateFailedFuture; import static com.google.common.util.concurrent.Futures.immediateFuture; import static com.google.common.util.concurrent.FuturesGetChecked.checkExceptionClassValidity; -import static com.google.common.util.concurrent.FuturesGetChecked.classValueValidator; import static com.google.common.util.concurrent.FuturesGetChecked.getChecked; import static com.google.common.util.concurrent.FuturesGetChecked.isCheckedException; import static com.google.common.util.concurrent.FuturesGetChecked.weakSetValidator; @@ -34,7 +33,7 @@ import java.io.IOException; import java.net.URISyntaxException; import java.security.GeneralSecurityException; -import java.security.acl.NotOwnerException; +import java.security.KeyException; import java.util.List; import java.util.TooManyListenersException; import java.util.concurrent.BrokenBarrierException; @@ -52,7 +51,7 @@ private enum Validator { NON_CACHING_WITH_CONSTRUCTOR_CHECK(nonCachingWithConstructorCheckValidator()), NON_CACHING_WITHOUT_CONSTRUCTOR_CHECK(nonCachingWithoutConstructorCheckValidator()), WEAK_SET(weakSetValidator()), - CLASS_VALUE(classValueValidator()); + ; final GetCheckedTypeValidator validator; @@ -92,7 +91,7 @@ private enum ExceptionType { ExecutionException.class, GeneralSecurityException.class, InvalidPreferencesFormatException.class, - NotOwnerException.class, + KeyException.class, RefreshFailedException.class, TimeoutException.class, TooManyListenersException.class, diff --git a/android/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBasedArrayBlockingQueue.java b/android/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBasedArrayBlockingQueue.java index 7998a729f3b9..2233fb47d978 100644 --- a/android/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBasedArrayBlockingQueue.java +++ b/android/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBasedArrayBlockingQueue.java @@ -25,7 +25,7 @@ import java.util.NoSuchElementException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * A bounded {@linkplain BlockingQueue blocking queue} backed by an array. This queue orders @@ -36,12 +36,12 @@ * *

    This is a classic "bounded buffer", in which a fixed-sized array holds elements * inserted by producers and extracted by consumers. Once created, the capacity cannot be increased. - * Attempts to put an element into a full queue will result in the operation blocking; - * attempts to take an element from an empty queue will similarly block. + * Attempts to {@code put} an element into a full queue will result in the operation blocking; + * attempts to {@code take} an element from an empty queue will similarly block. * *

    This class supports an optional fairness policy for ordering waiting producer and consumer * threads. By default, this ordering is not guaranteed. However, a queue constructed with fairness - * set to true grants threads access in FIFO order. Fairness generally decreases throughput + * set to {@code true} grants threads access in FIFO order. Fairness generally decreases throughput * but reduces variability and avoids starvation. * *

    This class and its iterator implement all of the optional methods of the {@link @@ -139,24 +139,24 @@ void removeAt(int i) { } /** - * Creates an MonitorBasedArrayBlockingQueue with the given (fixed) capacity and default + * Creates an {@code MonitorBasedArrayBlockingQueue} with the given (fixed) capacity and default * access policy. * * @param capacity the capacity of this queue - * @throws IllegalArgumentException if capacity is less than 1 + * @throws IllegalArgumentException if {@code capacity} is less than 1 */ public MonitorBasedArrayBlockingQueue(int capacity) { this(capacity, false); } /** - * Creates an MonitorBasedArrayBlockingQueue with the given (fixed) capacity and the + * Creates an {@code MonitorBasedArrayBlockingQueue} with the given (fixed) capacity and the * specified access policy. * * @param capacity the capacity of this queue - * @param fair if true then queue accesses for threads blocked on insertion or removal, - * are processed in FIFO order; if false the access order is unspecified. - * @throws IllegalArgumentException if capacity is less than 1 + * @param fair if {@code true} then queue accesses for threads blocked on insertion or removal, + * are processed in FIFO order; if {@code false} the access order is unspecified. + * @throws IllegalArgumentException if {@code capacity} is less than 1 */ public MonitorBasedArrayBlockingQueue(int capacity, boolean fair) { if (capacity <= 0) throw new IllegalArgumentException(); @@ -179,15 +179,15 @@ public boolean isSatisfied() { } /** - * Creates an MonitorBasedArrayBlockingQueue with the given (fixed) capacity, the + * Creates an {@code MonitorBasedArrayBlockingQueue} with the given (fixed) capacity, the * specified access policy and initially containing the elements of the given collection, added in * traversal order of the collection's iterator. * * @param capacity the capacity of this queue - * @param fair if true then queue accesses for threads blocked on insertion or removal, - * are processed in FIFO order; if false the access order is unspecified. + * @param fair if {@code true} then queue accesses for threads blocked on insertion or removal, + * are processed in FIFO order; if {@code false} the access order is unspecified. * @param c the collection of elements to initially contain - * @throws IllegalArgumentException if capacity is less than c.size(), or less + * @throws IllegalArgumentException if {@code capacity} is less than {@code c.size()}, or less * than 1. * @throws NullPointerException if the specified collection or any of its elements are null */ @@ -205,11 +205,11 @@ private static E[] newEArray(int capacity) { /** * Inserts the specified element at the tail of this queue if it is possible to do so immediately - * without exceeding the queue's capacity, returning true upon success and throwing an - * IllegalStateException if this queue is full. + * without exceeding the queue's capacity, returning {@code true} upon success and throwing an + * {@code IllegalStateException} if this queue is full. * * @param e the element to add - * @return true (as specified by {@link Collection#add}) + * @return {@code true} (as specified by {@link Collection#add}) * @throws IllegalStateException if this queue is full * @throws NullPointerException if the specified element is null */ @@ -220,7 +220,7 @@ public boolean add(E e) { /** * Inserts the specified element at the tail of this queue if it is possible to do so immediately - * without exceeding the queue's capacity, returning true upon success and false + * without exceeding the queue's capacity, returning {@code true} upon success and {@code false} * if this queue is full. This method is generally preferable to method {@link #add}, which can * fail to insert an element only by throwing an exception. * @@ -361,11 +361,11 @@ public int size() { /** * Returns the number of additional elements that this queue can ideally (in the absence of memory * or resource constraints) accept without blocking. This is always equal to the initial capacity - * of this queue less the current size of this queue. + * of this queue less the current {@code size} of this queue. * *

    Note that you cannot always tell if an attempt to insert an element will succeed by - * inspecting remainingCapacity because it may be the case that another thread is about - * to insert or remove an element. + * inspecting {@code remainingCapacity} because it may be the case that another thread is about to + * insert or remove an element. */ @Override public int remainingCapacity() { @@ -380,15 +380,15 @@ public int remainingCapacity() { /** * Removes a single instance of the specified element from this queue, if it is present. More - * formally, removes an element e such that o.equals(e), if this queue contains - * one or more such elements. Returns true if this queue contained the specified element + * formally, removes an element {@code e} such that {@code o.equals(e)}, if this queue contains + * one or more such elements. Returns {@code true} if this queue contained the specified element * (or equivalently, if this queue changed as a result of the call). * * @param o element to be removed from this queue, if present - * @return true if this queue changed as a result of the call + * @return {@code true} if this queue changed as a result of the call */ @Override - public boolean remove(@NullableDecl Object o) { + public boolean remove(@CheckForNull Object o) { if (o == null) return false; final E[] items = this.items; final Monitor monitor = this.monitor; @@ -410,15 +410,15 @@ public boolean remove(@NullableDecl Object o) { } /** - * Returns true if this queue contains the specified element. More formally, returns - * true if and only if this queue contains at least one element e such that - * o.equals(e). + * Returns {@code true} if this queue contains the specified element. More formally, returns + * {@code true} if and only if this queue contains at least one element {@code e} such that {@code + * o.equals(e)}. * * @param o object to be checked for containment in this queue - * @return true if this queue contains the specified element + * @return {@code true} if this queue contains the specified element */ @Override - public boolean contains(@NullableDecl Object o) { + public boolean contains(@CheckForNull Object o) { if (o == null) return false; final E[] items = this.items; final Monitor monitor = this.monitor; @@ -474,19 +474,19 @@ public Object[] toArray() { * *

    If this queue fits in the specified array with room to spare (i.e., the array has more * elements than this queue), the element in the array immediately following the end of the queue - * is set to null. + * is set to {@code null}. * *

    Like the {@link #toArray()} method, this method acts as bridge between array-based and * collection-based APIs. Further, this method allows precise control over the runtime type of the * output array, and may, under certain circumstances, be used to save allocation costs. * - *

    Suppose x is a queue known to contain only strings. The following code can be used - * to dump the queue into a newly allocated array of String: + *

    Suppose {@code x} is a queue known to contain only strings. The following code can be used + * to dump the queue into a newly allocated array of {@code String}: * *

        *     String[] y = x.toArray(new String[0]);
    * - *

    Note that toArray(new Object[0]) is identical in function to toArray(). + *

    Note that {@code toArray(new Object[0])} is identical in function to {@code toArray()}. * * @param a the array into which the elements of the queue are to be stored, if it is big enough; * otherwise, a new array of the same runtime type is allocated for this purpose @@ -626,8 +626,8 @@ public int drainTo(Collection c, int maxElements) { } /** - * Returns an iterator over the elements in this queue in proper sequence. The returned - * Iterator is a "weakly consistent" iterator that will never throw {@link + * Returns an iterator over the elements in this queue in proper sequence. The returned {@code + * Iterator} is a "weakly consistent" iterator that will never throw {@link * ConcurrentModificationException}, and guarantees to traverse elements as they existed upon * construction of the iterator, and may (but is not guaranteed to) reflect any modifications * subsequent to construction. diff --git a/android/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBasedPriorityBlockingQueue.java b/android/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBasedPriorityBlockingQueue.java index 715a9c815097..f61885be2630 100644 --- a/android/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBasedPriorityBlockingQueue.java +++ b/android/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBasedPriorityBlockingQueue.java @@ -30,28 +30,28 @@ import java.util.SortedSet; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * An unbounded {@linkplain BlockingQueue blocking queue} that uses the same ordering rules as class * {@link PriorityQueue} and supplies blocking retrieval operations. While this queue is logically - * unbounded, attempted additions may fail due to resource exhaustion (causing - * OutOfMemoryError). This class does not permit null elements. A priority queue - * relying on {@linkplain Comparable natural ordering} also does not permit insertion of - * non-comparable objects (doing so results in ClassCastException). + * unbounded, attempted additions may fail due to resource exhaustion (causing {@code + * OutOfMemoryError}). This class does not permit {@code null} elements. A priority queue relying on + * {@linkplain Comparable natural ordering} also does not permit insertion of non-comparable objects + * (doing so results in {@code ClassCastException}). * *

    This class and its iterator implement all of the optional methods of the {@link * Collection} and {@link Iterator} interfaces. The Iterator provided in method {@link #iterator()} * is not guaranteed to traverse the elements of the MonitorBasedPriorityBlockingQueue in - * any particular order. If you need ordered traversal, consider using - * Arrays.sort(pq.toArray()). Also, method drainTo can be used to remove - * some or all elements in priority order and place them in another collection. + * any particular order. If you need ordered traversal, consider using {@code + * Arrays.sort(pq.toArray())}. Also, method {@code drainTo} can be used to remove some or + * all elements in priority order and place them in another collection. * *

    Operations on this class make no guarantees about the ordering of elements with equal * priority. If you need to enforce an ordering, you can define custom classes or comparators that * use a secondary key to break ties in primary priority values. For example, here is a class that * applies first-in-first-out tie-breaking to comparable elements. To use it, you would insert a - * new FIFOEntry(anEntry) instead of a plain entry object. + * {@code new FIFOEntry(anEntry)} instead of a plain entry object. * *

      * class FIFOEntry<E extends Comparable<? super E>>
    @@ -96,40 +96,40 @@ public boolean isSatisfied() {
           };
     
       /**
    -   * Creates a MonitorBasedPriorityBlockingQueue with the default initial capacity (11)
    -   * that orders its elements according to their {@linkplain Comparable natural ordering}.
    +   * Creates a {@code MonitorBasedPriorityBlockingQueue} with the default initial capacity (11) that
    +   * orders its elements according to their {@linkplain Comparable natural ordering}.
        */
       public MonitorBasedPriorityBlockingQueue() {
         q = new PriorityQueue();
       }
     
       /**
    -   * Creates a MonitorBasedPriorityBlockingQueue with the specified initial capacity that
    +   * Creates a {@code MonitorBasedPriorityBlockingQueue} with the specified initial capacity that
        * orders its elements according to their {@linkplain Comparable natural ordering}.
        *
        * @param initialCapacity the initial capacity for this priority queue
    -   * @throws IllegalArgumentException if initialCapacity is less than 1
    +   * @throws IllegalArgumentException if {@code initialCapacity} is less than 1
        */
       public MonitorBasedPriorityBlockingQueue(int initialCapacity) {
         q = new PriorityQueue(initialCapacity, null);
       }
     
       /**
    -   * Creates a MonitorBasedPriorityBlockingQueue with the specified initial capacity that
    +   * Creates a {@code MonitorBasedPriorityBlockingQueue} with the specified initial capacity that
        * orders its elements according to the specified comparator.
        *
        * @param initialCapacity the initial capacity for this priority queue
        * @param comparator the comparator that will be used to order this priority queue. If {@code
        *     null}, the {@linkplain Comparable natural ordering} of the elements will be used.
    -   * @throws IllegalArgumentException if initialCapacity is less than 1
    +   * @throws IllegalArgumentException if {@code initialCapacity} is less than 1
        */
       public MonitorBasedPriorityBlockingQueue(
    -      int initialCapacity, @NullableDecl Comparator comparator) {
    +      int initialCapacity, @CheckForNull Comparator comparator) {
         q = new PriorityQueue(initialCapacity, comparator);
       }
     
       /**
    -   * Creates a MonitorBasedPriorityBlockingQueue containing the elements in the specified
    +   * Creates a {@code MonitorBasedPriorityBlockingQueue} containing the elements in the specified
        * collection. If the specified collection is a {@link SortedSet} or a {@link PriorityQueue}, this
        * priority queue will be ordered according to the same ordering. Otherwise, this priority queue
        * will be ordered according to the {@linkplain Comparable natural ordering} of its elements.
    @@ -147,7 +147,7 @@ public MonitorBasedPriorityBlockingQueue(Collection c) {
        * Inserts the specified element into this priority queue.
        *
        * @param e the element to add
    -   * @return true (as specified by {@link Collection#add})
    +   * @return {@code true} (as specified by {@link Collection#add})
        * @throws ClassCastException if the specified element cannot be compared with elements currently
        *     in the priority queue according to the priority queue's ordering
        * @throws NullPointerException if the specified element is null
    @@ -161,7 +161,7 @@ public boolean add(E e) {
        * Inserts the specified element into this priority queue.
        *
        * @param e the element to add
    -   * @return true (as specified by {@link Queue#offer})
    +   * @return {@code true} (as specified by {@link Queue#offer})
        * @throws ClassCastException if the specified element cannot be compared with elements currently
        *     in the priority queue according to the priority queue's ordering
        * @throws NullPointerException if the specified element is null
    @@ -188,7 +188,7 @@ public boolean offer(E e) {
        * @param e the element to add
        * @param timeout This parameter is ignored as the method never blocks
        * @param unit This parameter is ignored as the method never blocks
    -   * @return true
    +   * @return {@code true}
        * @throws ClassCastException if the specified element cannot be compared with elements currently
        *     in the priority queue according to the priority queue's ordering
        * @throws NullPointerException if the specified element is null
    @@ -261,10 +261,10 @@ public E peek() {
       }
     
       /**
    -   * Returns the comparator used to order the elements in this queue, or null if this queue
    +   * Returns the comparator used to order the elements in this queue, or {@code null} if this queue
        * uses the {@linkplain Comparable natural ordering} of its elements.
        *
    -   * @return the comparator used to order the elements in this queue, or null if this queue
    +   * @return the comparator used to order the elements in this queue, or {@code null} if this queue
        *     uses the natural ordering of its elements
        */
       public Comparator comparator() {
    @@ -283,10 +283,10 @@ public int size() {
       }
     
       /**
    -   * Always returns Integer.MAX_VALUE because a MonitorBasedPriorityBlockingQueue
    -   * is not capacity constrained.
    +   * Always returns {@code Integer.MAX_VALUE} because a {@code MonitorBasedPriorityBlockingQueue} is
    +   * not capacity constrained.
        *
    -   * @return Integer.MAX_VALUE
    +   * @return {@code Integer.MAX_VALUE}
        */
       @Override
       public int remainingCapacity() {
    @@ -300,10 +300,10 @@ public int remainingCapacity() {
        * specified element (or equivalently, if this queue changed as a result of the call).
        *
        * @param o element to be removed from this queue, if present
    -   * @return true if this queue changed as a result of the call
    +   * @return {@code true} if this queue changed as a result of the call
        */
       @Override
    -  public boolean remove(@NullableDecl Object o) {
    +  public boolean remove(@CheckForNull Object o) {
         final Monitor monitor = this.monitor;
         monitor.enter();
         try {
    @@ -319,10 +319,10 @@ public boolean remove(@NullableDecl Object o) {
        * o.equals(e)}.
        *
        * @param o object to be checked for containment in this queue
    -   * @return true if this queue contains the specified element
    +   * @return {@code true} if this queue contains the specified element
        */
       @Override
    -  public boolean contains(@NullableDecl Object o) {
    +  public boolean contains(@CheckForNull Object o) {
         final Monitor monitor = this.monitor;
         monitor.enter();
         try {
    @@ -363,19 +363,19 @@ public Object[] toArray() {
        *
        * 

    If this queue fits in the specified array with room to spare (i.e., the array has more * elements than this queue), the element in the array immediately following the end of the queue - * is set to null. + * is set to {@code null}. * *

    Like the {@link #toArray()} method, this method acts as bridge between array-based and * collection-based APIs. Further, this method allows precise control over the runtime type of the * output array, and may, under certain circumstances, be used to save allocation costs. * - *

    Suppose x is a queue known to contain only strings. The following code can be used - * to dump the queue into a newly allocated array of String: + *

    Suppose {@code x} is a queue known to contain only strings. The following code can be used + * to dump the queue into a newly allocated array of {@code String}: * *

        *     String[] y = x.toArray(new String[0]);
    * - *

    Note that toArray(new Object[0]) is identical in function to toArray(). + *

    Note that {@code toArray(new Object[0])} is identical in function to {@code toArray()}. * * @param a the array into which the elements of the queue are to be stored, if it is big enough; * otherwise, a new array of the same runtime type is allocated for this purpose @@ -474,7 +474,7 @@ public void clear() { /** * Returns an iterator over the elements in this queue. The iterator does not return the elements - * in any particular order. The returned Iterator is a "weakly consistent" iterator that + * in any particular order. The returned {@code Iterator} is a "weakly consistent" iterator that * will never throw {@link ConcurrentModificationException}, and guarantees to traverse elements * as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect * any modifications subsequent to construction. diff --git a/android/guava-tests/pom.xml b/android/guava-tests/pom.xml index 5f56f4b3a0bd..13a8d8dc11f7 100644 --- a/android/guava-tests/pom.xml +++ b/android/guava-tests/pom.xml @@ -5,7 +5,7 @@ com.google.guava guava-parent - HEAD-android-SNAPSHOT + 31.1-android guava-tests Guava Unit Tests @@ -25,10 +25,6 @@ com.google.code.findbugs jsr305 - - org.checkerframework - checker-compat-qual - com.google.errorprone error_prone_annotations @@ -102,6 +98,9 @@ org.codehaus.mojo animal-sniffer-maven-plugin + + false + org.codehaus.mojo diff --git a/android/guava-tests/test/com/google/common/base/AbstractIteratorTest.java b/android/guava-tests/test/com/google/common/base/AbstractIteratorTest.java index da732bf54946..ddb7d709739a 100644 --- a/android/guava-tests/test/com/google/common/base/AbstractIteratorTest.java +++ b/android/guava-tests/test/com/google/common/base/AbstractIteratorTest.java @@ -205,7 +205,7 @@ protected Integer computeNext() { // hasNext/next), but we'll cop out for now, knowing that // next() both start by invoking hasNext() anyway. - /** Throws a undeclared checked exception. */ + /** Throws an undeclared checked exception. */ private static void sneakyThrow(Throwable t) { class SneakyThrower { @SuppressWarnings("unchecked") // intentionally unsafe for test diff --git a/android/guava-tests/test/com/google/common/base/AsciiTest.java b/android/guava-tests/test/com/google/common/base/AsciiTest.java index d3a1f8f6597e..9e6b0e41ab86 100644 --- a/android/guava-tests/test/com/google/common/base/AsciiTest.java +++ b/android/guava-tests/test/com/google/common/base/AsciiTest.java @@ -54,8 +54,8 @@ public void testToUpperCase() { public void testCharsIgnored() { for (char c : IGNORED.toCharArray()) { String str = String.valueOf(c); - assertTrue(str, c == Ascii.toLowerCase(c)); - assertTrue(str, c == Ascii.toUpperCase(c)); + assertEquals(str, c, Ascii.toLowerCase(c)); + assertEquals(str, c, Ascii.toUpperCase(c)); assertFalse(str, Ascii.isLowerCase(c)); assertFalse(str, Ascii.isUpperCase(c)); } @@ -98,27 +98,26 @@ public void testTruncate() { } public void testTruncateIllegalArguments() { - String truncated = null; try { - truncated = Ascii.truncate("foobar", 2, "..."); + Ascii.truncate("foobar", 2, "..."); fail(); } catch (IllegalArgumentException expected) { } try { - truncated = Ascii.truncate("foobar", 8, "1234567890"); + Ascii.truncate("foobar", 8, "1234567890"); fail(); } catch (IllegalArgumentException expected) { } try { - truncated = Ascii.truncate("foobar", -1, "..."); + Ascii.truncate("foobar", -1, "..."); fail(); } catch (IllegalArgumentException expected) { } try { - truncated = Ascii.truncate("foobar", -1, ""); + Ascii.truncate("foobar", -1, ""); fail(); } catch (IllegalArgumentException expected) { } diff --git a/android/guava-tests/test/com/google/common/base/CharMatcherTest.java b/android/guava-tests/test/com/google/common/base/CharMatcherTest.java index 5412882c5641..49bdbbaffe25 100644 --- a/android/guava-tests/test/com/google/common/base/CharMatcherTest.java +++ b/android/guava-tests/test/com/google/common/base/CharMatcherTest.java @@ -386,7 +386,7 @@ private void reallyTestOneCharNoMatch(CharMatcher matcher, String s) { assertSame(s, matcher.replaceFrom(s, 'z')); assertSame(s, matcher.replaceFrom(s, "ZZ")); assertSame(s, matcher.trimFrom(s)); - assertSame(0, matcher.countIn(s)); + assertEquals(0, matcher.countIn(s)); } private void reallyTestMatchThenNoMatch(CharMatcher matcher, String s) { diff --git a/android/guava-tests/test/com/google/common/base/OptionalTest.java b/android/guava-tests/test/com/google/common/base/OptionalTest.java index 1f542f02411a..74178e2e52ba 100644 --- a/android/guava-tests/test/com/google/common/base/OptionalTest.java +++ b/android/guava-tests/test/com/google/common/base/OptionalTest.java @@ -68,6 +68,7 @@ public void testIsPresent_no() { assertFalse(Optional.absent().isPresent()); } + @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional public void testIsPresent_yes() { assertTrue(Optional.of("training").isPresent()); } @@ -85,6 +86,7 @@ public void testGet_present() { assertEquals("training", Optional.of("training").get()); } + @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional public void testOr_T_present() { assertEquals("a", Optional.of("a").or("default")); } @@ -93,6 +95,7 @@ public void testOr_T_absent() { assertEquals("default", Optional.absent().or("default")); } + @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional public void testOr_supplier_present() { assertEquals("a", Optional.of("a").or(Suppliers.ofInstance("fallback"))); } @@ -111,11 +114,13 @@ public void testOr_nullSupplier_absent() { } } + @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional public void testOr_nullSupplier_present() { Supplier nullSupplier = Suppliers.ofInstance(null); assertEquals("a", Optional.of("a").or(nullSupplier)); } + @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional public void testOr_Optional_present() { assertEquals(Optional.of("a"), Optional.of("a").or(Optional.of("fallback"))); } @@ -124,6 +129,7 @@ public void testOr_Optional_absent() { assertEquals(Optional.of("fallback"), Optional.absent().or(Optional.of("fallback"))); } + @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional public void testOrNull_present() { assertEquals("a", Optional.of("a").orNull()); } diff --git a/android/guava-tests/test/com/google/common/base/PreconditionsTest.java b/android/guava-tests/test/com/google/common/base/PreconditionsTest.java index 072649f99da1..1add44d32386 100644 --- a/android/guava-tests/test/com/google/common/base/PreconditionsTest.java +++ b/android/guava-tests/test/com/google/common/base/PreconditionsTest.java @@ -24,7 +24,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.testing.ArbitraryInstances; -import com.google.common.testing.NullPointerTester; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; @@ -539,8 +538,22 @@ public void overloadSelection() { @GwtIncompatible // NullPointerTester public void testNullPointers() { - NullPointerTester tester = new NullPointerTester(); - tester.testAllPublicStaticMethods(Preconditions.class); + /* + * Don't bother testing: Preconditions defines a bunch of methods that accept a template (or + * even entire message) that simultaneously: + * + * - _shouldn't_ be null, so we don't annotate it with @Nullable + * + * - _can_ be null without causing a runtime failure (because we don't want the interesting + * details of precondition failure to be hidden by an exception we throw about an unexpectedly + * null _failure message_) + * + * That combination upsets NullPointerTester, which wants any call that passes null for a + * non-@Nullable parameter to trigger a NullPointerException. + * + * (We still define this empty method to keep PackageSanityTests from generating its own + * automated nullness tests, which would fail.) + */ } private static final Object IGNORE_ME = diff --git a/android/guava-tests/test/com/google/common/base/ToStringHelperTest.java b/android/guava-tests/test/com/google/common/base/ToStringHelperTest.java index 3f1ef0f9e829..db15f2ef811c 100644 --- a/android/guava-tests/test/com/google/common/base/ToStringHelperTest.java +++ b/android/guava-tests/test/com/google/common/base/ToStringHelperTest.java @@ -116,15 +116,15 @@ class LocalInnerNestedClass {} @GwtIncompatible // Class names are obfuscated in GWT public void testToStringHelper_moreThanNineAnonymousClasses() { // The nth anonymous class has a name ending like "Outer.$n" - Object o1 = new Object() {}; - Object o2 = new Object() {}; - Object o3 = new Object() {}; - Object o4 = new Object() {}; - Object o5 = new Object() {}; - Object o6 = new Object() {}; - Object o7 = new Object() {}; - Object o8 = new Object() {}; - Object o9 = new Object() {}; + Object unused1 = new Object() {}; + Object unused2 = new Object() {}; + Object unused3 = new Object() {}; + Object unused4 = new Object() {}; + Object unused5 = new Object() {}; + Object unused6 = new Object() {}; + Object unused7 = new Object() {}; + Object unused8 = new Object() {}; + Object unused9 = new Object() {}; Object o10 = new Object() {}; String toTest = MoreObjects.toStringHelper(o10).toString(); assertEquals("{}", toTest); @@ -132,15 +132,15 @@ public void testToStringHelper_moreThanNineAnonymousClasses() { public void testToStringHelperLenient_moreThanNineAnonymousClasses() { // The nth anonymous class has a name ending like "Outer.$n" - Object o1 = new Object() {}; - Object o2 = new Object() {}; - Object o3 = new Object() {}; - Object o4 = new Object() {}; - Object o5 = new Object() {}; - Object o6 = new Object() {}; - Object o7 = new Object() {}; - Object o8 = new Object() {}; - Object o9 = new Object() {}; + Object unused1 = new Object() {}; + Object unused2 = new Object() {}; + Object unused3 = new Object() {}; + Object unused4 = new Object() {}; + Object unused5 = new Object() {}; + Object unused6 = new Object() {}; + Object unused7 = new Object() {}; + Object unused8 = new Object() {}; + Object unused9 = new Object() {}; Object o10 = new Object() {}; String toTest = MoreObjects.toStringHelper(o10).toString(); assertTrue(toTest, toTest.matches(".*\\{\\}")); @@ -357,7 +357,7 @@ public void testToStringOmitNullValues_manyFieldsLastNull() { } @GwtIncompatible // Class names are obfuscated in GWT - public void testToStringOmitNullValues_oneValue() { + public void testToStringOmitEmptyValues_oneValue() { String toTest = MoreObjects.toStringHelper(new TestClass()).omitNullValues().addValue(null).toString(); assertEquals("TestClass{}", toTest); diff --git a/android/guava-tests/test/com/google/common/base/VerifyTest.java b/android/guava-tests/test/com/google/common/base/VerifyTest.java index 03d2c2ff4a28..37c6efc1a990 100644 --- a/android/guava-tests/test/com/google/common/base/VerifyTest.java +++ b/android/guava-tests/test/com/google/common/base/VerifyTest.java @@ -19,11 +19,12 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; import junit.framework.AssertionFailedError; import junit.framework.TestCase; /** Unit test for {@link com.google.common.base.Verify}. */ -@GwtCompatible +@GwtCompatible(emulated = true) public class VerifyTest extends TestCase { public void testVerify_simple_success() { verify(true); @@ -92,6 +93,11 @@ public void testVerifyNotNull_simpleMessage_failure() { } } + @GwtIncompatible // NullPointerTester + public void testNullPointers() { + // Don't bother testing: Verify is like Preconditions. See the discussion on that class. + } + private static final Object IGNORE_ME = new Object() { @Override diff --git a/android/guava-tests/test/com/google/common/cache/CacheBuilderFactory.java b/android/guava-tests/test/com/google/common/cache/CacheBuilderFactory.java index 04b6f1ef5d6a..948b4b560467 100644 --- a/android/guava-tests/test/com/google/common/cache/CacheBuilderFactory.java +++ b/android/guava-tests/test/com/google/common/cache/CacheBuilderFactory.java @@ -26,7 +26,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Helper class for creating {@link CacheBuilder} instances with all combinations of several sets of @@ -120,7 +120,7 @@ public CacheBuilder apply(List combination) { private static final Function> NULLABLE_TO_OPTIONAL = new Function>() { @Override - public Optional apply(@NullableDecl Object obj) { + public Optional apply(@CheckForNull Object obj) { return Optional.fromNullable(obj); } }; diff --git a/android/guava-tests/test/com/google/common/cache/CacheTesting.java b/android/guava-tests/test/com/google/common/cache/CacheTesting.java index 255a89480ff2..4c58ed50272c 100644 --- a/android/guava-tests/test/com/google/common/cache/CacheTesting.java +++ b/android/guava-tests/test/com/google/common/cache/CacheTesting.java @@ -44,7 +44,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReferenceArray; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * A collection of utilities for {@link Cache} testing. @@ -367,7 +367,7 @@ static void processPendingNotifications(Cache cache) { } interface Receiver { - void accept(@NullableDecl T object); + void accept(@CheckForNull T object); } /** diff --git a/android/guava-tests/test/com/google/common/cache/LocalCacheTest.java b/android/guava-tests/test/com/google/common/cache/LocalCacheTest.java index 3c4529cafc0f..b8ec7dfe6882 100644 --- a/android/guava-tests/test/com/google/common/cache/LocalCacheTest.java +++ b/android/guava-tests/test/com/google/common/cache/LocalCacheTest.java @@ -232,7 +232,7 @@ public void tearDown() throws Exception { private Throwable popLoggedThrowable() { List logRecords = logHandler.getStoredLogRecords(); - assertSame(1, logRecords.size()); + assertEquals(1, logRecords.size()); LogRecord logRecord = logRecords.get(0); logHandler.clear(); return logRecord.getThrown(); diff --git a/android/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java b/android/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java index 8507e68f2eb9..6cc02602126e 100644 --- a/android/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java +++ b/android/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java @@ -23,7 +23,7 @@ import com.google.common.util.concurrent.ListenableFuture; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Utility {@link CacheLoader} implementations intended for use in testing. @@ -57,7 +57,7 @@ public Map loadAll(Iterable keys) throws Exception { } /** Returns a {@link CacheLoader} that returns the given {@code constant} for every request. */ - static ConstantLoader constantLoader(@NullableDecl V constant) { + static ConstantLoader constantLoader(@CheckForNull V constant) { return new ConstantLoader<>(constant); } diff --git a/android/guava-tests/test/com/google/common/collect/AbstractIteratorTest.java b/android/guava-tests/test/com/google/common/collect/AbstractIteratorTest.java index 35922105f196..a76907cda7c7 100644 --- a/android/guava-tests/test/com/google/common/collect/AbstractIteratorTest.java +++ b/android/guava-tests/test/com/google/common/collect/AbstractIteratorTest.java @@ -250,6 +250,7 @@ public Integer computeNext() { } } + @SuppressWarnings("DoNotCall") public void testCantRemove() { Iterator iter = new AbstractIterator() { diff --git a/android/guava-tests/test/com/google/common/collect/AbstractMapEntryTest.java b/android/guava-tests/test/com/google/common/collect/AbstractMapEntryTest.java index 11c66a702375..63c17dedaeca 100644 --- a/android/guava-tests/test/com/google/common/collect/AbstractMapEntryTest.java +++ b/android/guava-tests/test/com/google/common/collect/AbstractMapEntryTest.java @@ -61,7 +61,8 @@ public void testToStringNull() { public void testEquals() { Entry foo1 = entry("foo", 1); - assertEquals(foo1, foo1); + // Explicitly call `equals`; `assertEquals` might return fast + assertTrue(foo1.equals(foo1)); assertEquals(control("foo", 1), foo1); assertEquals(control("bar", 2), entry("bar", 2)); assertFalse(control("foo", 1).equals(entry("foo", 2))); diff --git a/android/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java b/android/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java index 5de3f8df2be1..b9e15fd9ca65 100644 --- a/android/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java +++ b/android/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java @@ -87,4 +87,48 @@ public void testBigIntegersOffsetExceptions() { } catch (IllegalArgumentException expected) { } } + + public void testCustomOffsetExceptions() { + try { + new MyIntegerDomain().offset(0, -1); + fail(); + } catch (IllegalArgumentException expected) { + } + try { + new MyIntegerDomain().offset(Integer.MAX_VALUE, 1); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + private static final class MyIntegerDomain extends DiscreteDomain { + static final DiscreteDomain DELEGATE = DiscreteDomain.integers(); + + @Override + public Integer next(Integer value) { + return DELEGATE.next(value); + } + + @Override + public Integer previous(Integer value) { + return DELEGATE.previous(value); + } + + // Do *not* override offset() to delegate: We want to test the default implementation. + + @Override + public long distance(Integer start, Integer end) { + return DELEGATE.distance(start, end); + } + + @Override + public Integer minValue() { + return DELEGATE.minValue(); + } + + @Override + public Integer maxValue() { + return DELEGATE.maxValue(); + } + } } diff --git a/android/guava-tests/test/com/google/common/collect/FluentIterableTest.java b/android/guava-tests/test/com/google/common/collect/FluentIterableTest.java index e623f31d2f36..b8427b1c8140 100644 --- a/android/guava-tests/test/com/google/common/collect/FluentIterableTest.java +++ b/android/guava-tests/test/com/google/common/collect/FluentIterableTest.java @@ -38,9 +38,9 @@ import java.util.Set; import java.util.SortedSet; import java.util.concurrent.TimeUnit; +import javax.annotation.CheckForNull; import junit.framework.AssertionFailedError; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Unit test for {@link FluentIterable}. @@ -850,7 +850,7 @@ public void testUniqueIndex_nullValue() { .uniqueIndex( new Function() { @Override - public Object apply(@NullableDecl Integer input) { + public Object apply(@CheckForNull Integer input) { return String.valueOf(input); } }); diff --git a/android/guava-tests/test/com/google/common/collect/ForwardingMapTest.java b/android/guava-tests/test/com/google/common/collect/ForwardingMapTest.java index cc5d73967607..cf2ed0d3b5f1 100644 --- a/android/guava-tests/test/com/google/common/collect/ForwardingMapTest.java +++ b/android/guava-tests/test/com/google/common/collect/ForwardingMapTest.java @@ -170,7 +170,7 @@ protected Map create(Entry[] entries) { for (Entry entry : entries) { builder.put(entry.getKey(), entry.getValue()); } - return new StandardImplForwardingMap<>(builder.build()); + return new StandardImplForwardingMap<>(builder.buildOrThrow()); } }) .named("ForwardingMap[ImmutableMap] with standard implementations") diff --git a/android/guava-tests/test/com/google/common/collect/ForwardingSortedMultisetTest.java b/android/guava-tests/test/com/google/common/collect/ForwardingSortedMultisetTest.java index d0673f1d0d7c..2b77cd5e4b74 100644 --- a/android/guava-tests/test/com/google/common/collect/ForwardingSortedMultisetTest.java +++ b/android/guava-tests/test/com/google/common/collect/ForwardingSortedMultisetTest.java @@ -27,10 +27,10 @@ import java.util.Iterator; import java.util.List; import java.util.NavigableSet; +import javax.annotation.CheckForNull; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Tests for {@link ForwardingSortedMultiset}. @@ -93,12 +93,12 @@ public SortedMultiset subMultiset( } @Override - public int count(@NullableDecl Object element) { + public int count(@CheckForNull Object element) { return standardCount(element); } @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { return standardEquals(object); } @@ -123,7 +123,7 @@ public void clear() { } @Override - public boolean contains(@NullableDecl Object object) { + public boolean contains(@CheckForNull Object object) { return standardContains(object); } @@ -143,7 +143,7 @@ public Iterator iterator() { } @Override - public boolean remove(@NullableDecl Object object) { + public boolean remove(@CheckForNull Object object) { return standardRemove(object); } diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java index b4f99725702a..e01b094fed93 100644 --- a/android/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java +++ b/android/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java @@ -32,6 +32,7 @@ import com.google.common.collect.testing.google.BiMapInverseTester; import com.google.common.collect.testing.google.BiMapTestSuiteBuilder; import com.google.common.testing.SerializableTester; +import java.util.AbstractMap; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; @@ -322,6 +323,7 @@ public void testBuilderPutNullValueViaPutAll() { } } + @SuppressWarnings("AlwaysThrows") public void testPuttingTheSameKeyTwiceThrowsOnBuild() { Builder builder = new Builder() @@ -395,6 +397,136 @@ public void testOf() { "four", 5, "five"); + assertMapEquals( + ImmutableBiMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6), + "one", + 1, + "two", + 2, + "three", + 3, + "four", + 4, + "five", + 5, + "six", + 6); + assertMapEquals( + ImmutableBiMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7), + "one", + 1, + "two", + 2, + "three", + 3, + "four", + 4, + "five", + 5, + "six", + 6, + "seven", + 7); + assertMapEquals( + ImmutableBiMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7, + "eight", 8), + "one", + 1, + "two", + 2, + "three", + 3, + "four", + 4, + "five", + 5, + "six", + 6, + "seven", + 7, + "eight", + 8); + assertMapEquals( + ImmutableBiMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7, + "eight", 8, + "nine", 9), + "one", + 1, + "two", + 2, + "three", + 3, + "four", + 4, + "five", + 5, + "six", + 6, + "seven", + 7, + "eight", + 8, + "nine", + 9); + assertMapEquals( + ImmutableBiMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7, + "eight", 8, + "nine", 9, + "ten", 10), + "one", + 1, + "two", + 2, + "three", + 3, + "four", + 4, + "five", + 5, + "six", + 6, + "seven", + 7, + "eight", + 8, + "nine", + 9, + "ten", + 10); } public void testOfNullKey() { @@ -425,6 +557,7 @@ public void testOfNullValue() { } } + @SuppressWarnings("AlwaysThrows") public void testOfWithDuplicateKey() { try { ImmutableBiMap.of("one", 1, "one", 1); @@ -434,6 +567,30 @@ public void testOfWithDuplicateKey() { } } + public void testOfEntries() { + assertMapEquals( + ImmutableBiMap.ofEntries(entry("one", 1), entry("two", 2)), "one", 1, "two", 2); + } + + public void testOfEntriesNull() { + Entry nullKey = entry(null, 23); + try { + ImmutableBiMap.ofEntries(nullKey); + fail(); + } catch (NullPointerException expected) { + } + Entry nullValue = entry(23, null); + try { + ImmutableBiMap.ofEntries(nullValue); + fail(); + } catch (NullPointerException expected) { + } + } + + private static Entry entry(T key, T value) { + return new AbstractMap.SimpleImmutableEntry<>(key, value); + } + public void testCopyOfEmptyMap() { ImmutableBiMap copy = ImmutableBiMap.copyOf(Collections.emptyMap()); @@ -485,7 +642,7 @@ public void testFromImmutableMap() { .put("three", 3) .put("four", 4) .put("five", 5) - .build()); + .buildOrThrow()); assertMapEquals(bimap, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); assertMapEquals(bimap.inverse(), 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); } @@ -497,13 +654,14 @@ public void testDuplicateValues() { .put("two", 2) .put("uno", 1) .put("dos", 2) - .build(); + .buildOrThrow(); try { ImmutableBiMap.copyOf(map); fail(); } catch (IllegalArgumentException expected) { - assertThat(expected.getMessage()).contains("1"); + assertThat(expected.getMessage()).containsMatch("1|2"); + // We don't specify which of the two dups should be reported. } } @@ -534,6 +692,7 @@ public void testToImmutableBiMap_exceptionOnDuplicateKey_java7_combine() { public static class BiMapSpecificTests extends TestCase { + @SuppressWarnings("DoNotCall") public void testForcePut() { BiMap bimap = ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, "two", 2)); try { @@ -593,11 +752,11 @@ public void testInverseSerialization() { } private static void assertMapEquals(Map map, Object... alternatingKeysAndValues) { - int i = 0; - for (Entry entry : map.entrySet()) { - assertEquals(alternatingKeysAndValues[i++], entry.getKey()); - assertEquals(alternatingKeysAndValues[i++], entry.getValue()); + Map expected = new LinkedHashMap<>(); + for (int i = 0; i < alternatingKeysAndValues.length; i += 2) { + expected.put(alternatingKeysAndValues[i], alternatingKeysAndValues[i + 1]); } + assertThat(map).containsExactlyEntriesIn(expected).inOrder(); } /** No-op test so that the class has at least one method, making Maven's test runner happy. */ diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java index 768ebecde560..126074004224 100644 --- a/android/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java +++ b/android/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java @@ -29,6 +29,7 @@ import com.google.common.collect.testing.google.TestStringListMultimapGenerator; import com.google.common.collect.testing.google.UnmodifiableCollectionTests; import com.google.common.testing.EqualsTester; +import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; import java.util.Arrays; import java.util.Collection; @@ -571,4 +572,13 @@ public void testEmptySerialization() { Multimap multimap = ImmutableListMultimap.of(); assertSame(multimap, SerializableTester.reserialize(multimap)); } + + @GwtIncompatible // reflection + public void testNulls() throws Exception { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicStaticMethods(ImmutableListMultimap.class); + tester.ignore(ImmutableListMultimap.class.getMethod("get", Object.class)); + tester.testAllPublicInstanceMethods(ImmutableListMultimap.of()); + tester.testAllPublicInstanceMethods(ImmutableListMultimap.of("a", 1)); + } } diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableMapTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableMapTest.java index fd27416c5922..898d2a4b490e 100644 --- a/android/guava-tests/test/com/google/common/collect/ImmutableMapTest.java +++ b/android/guava-tests/test/com/google/common/collect/ImmutableMapTest.java @@ -18,6 +18,7 @@ import static com.google.common.testing.SerializableTester.reserialize; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; @@ -49,12 +50,15 @@ import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.util.AbstractMap; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; @@ -66,6 +70,7 @@ * @author Jesse Wilson */ @GwtCompatible(emulated = true) +@SuppressWarnings("AlwaysThrows") public class ImmutableMapTest extends TestCase { @GwtIncompatible // suite @@ -176,7 +181,7 @@ protected Map makeEmptyMap() { throw new UnsupportedOperationException(); } - private static final Joiner joiner = Joiner.on(", "); + private static final Joiner JOINER = Joiner.on(", "); @Override protected void assertMoreInvariants(Map map) { @@ -185,10 +190,10 @@ protected void assertMoreInvariants(Map map) { assertEquals(entry.getKey() + "=" + entry.getValue(), entry.toString()); } - assertEquals("{" + joiner.join(map.entrySet()) + "}", map.toString()); - assertEquals("[" + joiner.join(map.entrySet()) + "]", map.entrySet().toString()); - assertEquals("[" + joiner.join(map.keySet()) + "]", map.keySet().toString()); - assertEquals("[" + joiner.join(map.values()) + "]", map.values().toString()); + assertEquals("{" + JOINER.join(map.entrySet()) + "}", map.toString()); + assertEquals("[" + JOINER.join(map.entrySet()) + "]", map.entrySet().toString()); + assertEquals("[" + JOINER.join(map.keySet()) + "]", map.keySet().toString()); + assertEquals("[" + JOINER.join(map.values()) + "]", map.values().toString()); assertEquals(MinimalSet.from(map.entrySet()), map.entrySet()); assertEquals(Sets.newHashSet(map.keySet()), map.keySet()); @@ -316,12 +321,13 @@ protected Map makePopulatedMap() { public static class CreationTests extends TestCase { public void testEmptyBuilder() { - ImmutableMap map = new Builder().build(); + ImmutableMap map = new Builder().buildOrThrow(); assertEquals(Collections.emptyMap(), map); } public void testSingletonBuilder() { - ImmutableMap map = new Builder().put("one", 1).build(); + ImmutableMap map = + new Builder().put("one", 1).buildOrThrow(); assertMapEquals(map, "one", 1); } @@ -333,7 +339,7 @@ public void testBuilder() { .put("three", 3) .put("four", 4) .put("five", 5) - .build(); + .buildOrThrow(); assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); } @@ -346,7 +352,7 @@ public void testBuilderExactlySizedReusesArray() { } Object[] builderArrayAfterPuts = builder.alternatingKeysAndValues; RegularImmutableMap map = - (RegularImmutableMap) builder.build(); + (RegularImmutableMap) builder.buildOrThrow(); Object[] mapInternalArray = map.alternatingKeysAndValues; assertSame(builderArray, builderArrayAfterPuts); assertSame(builderArray, mapInternalArray); @@ -361,16 +367,16 @@ public void testBuilder_orderEntriesByValue() { .put("five", 5) .put("four", 4) .put("two", 2) - .build(); + .buildOrThrow(); assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); } public void testBuilder_orderEntriesByValueAfterExactSizeBuild() { Builder builder = new Builder(2).put("four", 4).put("one", 1); - ImmutableMap keyOrdered = builder.build(); + ImmutableMap keyOrdered = builder.buildOrThrow(); ImmutableMap valueOrdered = - builder.orderEntriesByValue(Ordering.natural()).build(); + builder.orderEntriesByValue(Ordering.natural()).buildOrThrow(); assertMapEquals(keyOrdered, "four", 4, "one", 1); assertMapEquals(valueOrdered, "one", 1, "four", 4); } @@ -385,9 +391,45 @@ public void testBuilder_orderEntriesByValue_usedTwiceFails() { } } + @GwtIncompatible // we haven't implemented this + public void testBuilder_orderEntriesByValue_keepingLast() { + ImmutableMap.Builder builder = + new Builder() + .orderEntriesByValue(Ordering.natural()) + .put("three", 3) + .put("one", 1) + .put("five", 5) + .put("four", 3) + .put("four", 5) + .put("four", 4) // this should win because it's last + .put("two", 2); + assertMapEquals( + builder.buildKeepingLast(), "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); + try { + builder.buildOrThrow(); + fail("Expected exception from duplicate keys"); + } catch (IllegalArgumentException expected) { + } + } + + @GwtIncompatible // we haven't implemented this + public void testBuilder_orderEntriesByValue_keepingLast_builderSizeFieldPreserved() { + ImmutableMap.Builder builder = + new Builder() + .orderEntriesByValue(Ordering.natural()) + .put("one", 1) + .put("one", 1); + assertMapEquals(builder.buildKeepingLast(), "one", 1); + try { + builder.buildOrThrow(); + fail("Expected exception from duplicate keys"); + } catch (IllegalArgumentException expected) { + } + } + public void testBuilder_withImmutableEntry() { ImmutableMap map = - new Builder().put(Maps.immutableEntry("one", 1)).build(); + new Builder().put(Maps.immutableEntry("one", 1)).buildOrThrow(); assertMapEquals(map, "one", 1); } @@ -428,12 +470,14 @@ public Integer getValue() { builder.put(entry); holder.string = "two"; - assertMapEquals(builder.build(), "one", 1); + assertMapEquals(builder.buildOrThrow(), "one", 1); } public void testBuilderPutAllWithEmptyMap() { ImmutableMap map = - new Builder().putAll(Collections.emptyMap()).build(); + new Builder() + .putAll(Collections.emptyMap()) + .buildOrThrow(); assertEquals(Collections.emptyMap(), map); } @@ -447,14 +491,14 @@ public void testBuilderPutAll() { moreToPut.put("five", 5); ImmutableMap map = - new Builder().putAll(toPut).putAll(moreToPut).build(); + new Builder().putAll(toPut).putAll(moreToPut).buildOrThrow(); assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); } public void testBuilderReuse() { Builder builder = new Builder<>(); - ImmutableMap mapOne = builder.put("one", 1).put("two", 2).build(); - ImmutableMap mapTwo = builder.put("three", 3).put("four", 4).build(); + ImmutableMap mapOne = builder.put("one", 1).put("two", 2).buildOrThrow(); + ImmutableMap mapTwo = builder.put("three", 3).put("four", 4).buildOrThrow(); assertMapEquals(mapOne, "one", 1, "two", 2); assertMapEquals(mapTwo, "one", 1, "two", 2, "three", 3, "four", 4); @@ -468,7 +512,7 @@ public void testBuilderPutNullKeyFailsAtomically() { } catch (NullPointerException expected) { } builder.put("foo", 2); - assertMapEquals(builder.build(), "foo", 2); + assertMapEquals(builder.buildOrThrow(), "foo", 2); } public void testBuilderPutImmutableEntryWithNullKeyFailsAtomically() { @@ -479,7 +523,7 @@ public void testBuilderPutImmutableEntryWithNullKeyFailsAtomically() { } catch (NullPointerException expected) { } builder.put("foo", 2); - assertMapEquals(builder.build(), "foo", 2); + assertMapEquals(builder.buildOrThrow(), "foo", 2); } // for GWT compatibility @@ -511,7 +555,7 @@ public void testBuilderPutMutableEntryWithNullKeyFailsAtomically() { } catch (NullPointerException expected) { } builder.put("foo", 2); - assertMapEquals(builder.build(), "foo", 2); + assertMapEquals(builder.buildOrThrow(), "foo", 2); } public void testBuilderPutNullKey() { @@ -554,15 +598,108 @@ public void testPuttingTheSameKeyTwiceThrowsOnBuild() { Builder builder = new Builder() .put("one", 1) - .put("one", 1); // throwing on this line would be even better + .put("one", 1); // throwing on this line might be better but it's too late to change try { - builder.build(); + builder.buildOrThrow(); fail(); } catch (IllegalArgumentException expected) { } } + public void testBuildKeepingLast_allowsOverwrite() { + Builder builder = + new Builder() + .put(1, "un") + .put(2, "deux") + .put(70, "soixante-dix") + .put(70, "septante") + .put(70, "seventy") + .put(1, "one") + .put(2, "two"); + ImmutableMap map = builder.buildKeepingLast(); + assertMapEquals(map, 1, "one", 2, "two", 70, "seventy"); + } + + public void testBuildKeepingLast_smallTableSameHash() { + String key1 = "QED"; + String key2 = "R&D"; + assertThat(key1.hashCode()).isEqualTo(key2.hashCode()); + ImmutableMap map = + ImmutableMap.builder() + .put(key1, 1) + .put(key2, 2) + .put(key1, 3) + .put(key2, 4) + .buildKeepingLast(); + assertMapEquals(map, key1, 3, key2, 4); + } + + // The java7 branch has different code depending on whether the entry indexes fit in a byte, + // short, or int. The small table in testBuildKeepingLast_allowsOverwrite will test the byte + // case. This method tests the short case. + public void testBuildKeepingLast_shortTable() { + Builder builder = ImmutableMap.builder(); + Map expected = new LinkedHashMap<>(); + for (int i = 0; i < 1000; i++) { + // Truncate to even key, so we have put(0, "0") then put(0, "1"). Half the entries are + // duplicates. + Integer key = i & ~1; + String value = String.valueOf(i); + builder.put(key, value); + expected.put(key, value); + } + ImmutableMap map = builder.buildKeepingLast(); + assertThat(map).hasSize(500); + assertThat(map).containsExactlyEntriesIn(expected).inOrder(); + } + + // This method tests the int case. + public void testBuildKeepingLast_bigTable() { + Builder builder = ImmutableMap.builder(); + Map expected = new LinkedHashMap<>(); + for (int i = 0; i < 200_000; i++) { + // Truncate to even key, so we have put(0, "0") then put(0, "1"). Half the entries are + // duplicates. + Integer key = i & ~1; + String value = String.valueOf(i); + builder.put(key, value); + expected.put(key, value); + } + ImmutableMap map = builder.buildKeepingLast(); + assertThat(map).hasSize(100_000); + assertThat(map).containsExactlyEntriesIn(expected).inOrder(); + } + + @GwtIncompatible // Pattern, Matcher + public void testBuilder_keepingLast_thenOrThrow() { + ImmutableMap.Builder builder = + new Builder() + .put("three", 3) + .put("one", 1) + .put("five", 5) + .put("four", 3) + .put("four", 5) + .put("four", 4) // this should win because it's last + .put("two", 2); + assertMapEquals( + builder.buildKeepingLast(), "three", 3, "one", 1, "five", 5, "four", 4, "two", 2); + try { + builder.buildOrThrow(); + fail("Expected exception from duplicate keys"); + } catch (IllegalArgumentException expected) { + // We don't really care which values the exception message contains, but they should be + // different from each other. If buildKeepingLast() collapsed duplicates, that might end up + // not being true. + Pattern pattern = + Pattern.compile("Multiple entries with same key: four=(.*) and four=(.*)"); + assertThat(expected).hasMessageThat().matches(pattern); + Matcher matcher = pattern.matcher(expected.getMessage()); + assertThat(matcher.matches()).isTrue(); + assertThat(matcher.group(1)).isNotEqualTo(matcher.group(2)); + } + } + public void testOf() { assertMapEquals(ImmutableMap.of("one", 1), "one", 1); assertMapEquals(ImmutableMap.of("one", 1, "two", 2), "one", 1, "two", 2); @@ -590,6 +727,136 @@ public void testOf() { 4, "five", 5); + assertMapEquals( + ImmutableMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6), + "one", + 1, + "two", + 2, + "three", + 3, + "four", + 4, + "five", + 5, + "six", + 6); + assertMapEquals( + ImmutableMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7), + "one", + 1, + "two", + 2, + "three", + 3, + "four", + 4, + "five", + 5, + "six", + 6, + "seven", + 7); + assertMapEquals( + ImmutableMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7, + "eight", 8), + "one", + 1, + "two", + 2, + "three", + 3, + "four", + 4, + "five", + 5, + "six", + 6, + "seven", + 7, + "eight", + 8); + assertMapEquals( + ImmutableMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7, + "eight", 8, + "nine", 9), + "one", + 1, + "two", + 2, + "three", + 3, + "four", + 4, + "five", + 5, + "six", + 6, + "seven", + 7, + "eight", + 8, + "nine", + 9); + assertMapEquals( + ImmutableMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7, + "eight", 8, + "nine", 9, + "ten", 10), + "one", + 1, + "two", + 2, + "three", + 3, + "four", + 4, + "five", + 5, + "six", + 6, + "seven", + 7, + "eight", + 8, + "nine", + 9, + "ten", + 10); } public void testOfNullKey() { @@ -745,12 +1012,11 @@ public void testNullPointers() { } private static void assertMapEquals(Map map, Object... alternatingKeysAndValues) { - assertEquals(map.size(), alternatingKeysAndValues.length / 2); - int i = 0; - for (Entry entry : map.entrySet()) { - assertEquals(alternatingKeysAndValues[i++], entry.getKey()); - assertEquals(alternatingKeysAndValues[i++], entry.getValue()); + Map expected = new LinkedHashMap<>(); + for (int i = 0; i < alternatingKeysAndValues.length; i += 2) { + expected.put(alternatingKeysAndValues[i], alternatingKeysAndValues[i + 1]); } + assertThat(map).containsExactlyEntriesIn(expected).inOrder(); } private static class IntHolder implements Serializable { @@ -849,15 +1115,87 @@ public void ignore_testSerializationNoDuplication_regularImmutableMap() throws E public void testEquals() { new EqualsTester() - .addEqualityGroup(ImmutableMap.of(), ImmutableMap.builder().build()) - .addEqualityGroup(ImmutableMap.of(1, 1), ImmutableMap.builder().put(1, 1).build()) - .addEqualityGroup(ImmutableMap.of(1, 1, 2, 2)) - .addEqualityGroup(ImmutableMap.of(1, 1, 2, 2, 3, 3)) - .addEqualityGroup(ImmutableMap.of(1, 4, 2, 2, 3, 3)) - .addEqualityGroup(ImmutableMap.of(1, 1, 2, 4, 3, 3)) - .addEqualityGroup(ImmutableMap.of(1, 1, 2, 2, 3, 4)) - .addEqualityGroup(ImmutableMap.of(1, 2, 2, 3, 3, 1)) - .addEqualityGroup(ImmutableMap.of(1, 1, 2, 2, 3, 3, 4, 4)) + .addEqualityGroup( + ImmutableMap.of(), + ImmutableMap.builder().buildOrThrow(), + ImmutableMap.ofEntries(), + map()) + .addEqualityGroup( + ImmutableMap.of(1, 1), + ImmutableMap.builder().put(1, 1).buildOrThrow(), + ImmutableMap.ofEntries(entry(1, 1)), + map(1, 1)) + .addEqualityGroup( + ImmutableMap.of(1, 1, 2, 2), + ImmutableMap.builder().put(1, 1).put(2, 2).buildOrThrow(), + ImmutableMap.ofEntries(entry(1, 1), entry(2, 2)), + map(1, 1, 2, 2)) + .addEqualityGroup( + ImmutableMap.of(1, 1, 2, 2, 3, 3), + ImmutableMap.builder().put(1, 1).put(2, 2).put(3, 3).buildOrThrow(), + ImmutableMap.ofEntries(entry(1, 1), entry(2, 2), entry(3, 3)), + map(1, 1, 2, 2, 3, 3)) + .addEqualityGroup( + ImmutableMap.of(1, 4, 2, 2, 3, 3), + ImmutableMap.builder().put(1, 4).put(2, 2).put(3, 3).buildOrThrow(), + ImmutableMap.ofEntries(entry(1, 4), entry(2, 2), entry(3, 3)), + map(1, 4, 2, 2, 3, 3)) + .addEqualityGroup( + ImmutableMap.of(1, 1, 2, 4, 3, 3), + ImmutableMap.builder().put(1, 1).put(2, 4).put(3, 3).buildOrThrow(), + ImmutableMap.ofEntries(entry(1, 1), entry(2, 4), entry(3, 3)), + map(1, 1, 2, 4, 3, 3)) + .addEqualityGroup( + ImmutableMap.of(1, 1, 2, 2, 3, 4), + ImmutableMap.builder().put(1, 1).put(2, 2).put(3, 4).buildOrThrow(), + ImmutableMap.ofEntries(entry(1, 1), entry(2, 2), entry(3, 4)), + map(1, 1, 2, 2, 3, 4)) + .addEqualityGroup( + ImmutableMap.of(1, 2, 2, 3, 3, 1), + ImmutableMap.builder().put(1, 2).put(2, 3).put(3, 1).buildOrThrow(), + ImmutableMap.ofEntries(entry(1, 2), entry(2, 3), entry(3, 1)), + map(1, 2, 2, 3, 3, 1)) + .addEqualityGroup( + ImmutableMap.of(1, 1, 2, 2, 3, 3, 4, 4), + ImmutableMap.builder().put(1, 1).put(2, 2).put(3, 3).put(4, 4).buildOrThrow(), + ImmutableMap.ofEntries(entry(1, 1), entry(2, 2), entry(3, 3), entry(4, 4)), + map(1, 1, 2, 2, 3, 3, 4, 4)) + .addEqualityGroup( + ImmutableMap.of(1, 1, 2, 2, 3, 3, 4, 4, 5, 5), + ImmutableMap.builder().put(1, 1).put(2, 2).put(3, 3).put(4, 4).put(5, 5).buildOrThrow(), + ImmutableMap.ofEntries(entry(1, 1), entry(2, 2), entry(3, 3), entry(4, 4), entry(5, 5)), + map(1, 1, 2, 2, 3, 3, 4, 4, 5, 5)) .testEquals(); } + + public void testOfEntriesNull() { + Entry nullKey = entry(null, 23); + try { + ImmutableMap.ofEntries(nullKey); + fail(); + } catch (NullPointerException expected) { + } + Entry nullValue = entry(23, null); + try { + ImmutableMap.ofEntries(nullValue); + fail(); + } catch (NullPointerException expected) { + } + } + + private static Map map(T... keysAndValues) { + assertThat(keysAndValues.length % 2).isEqualTo(0); + LinkedHashMap map = new LinkedHashMap<>(); + for (int i = 0; i < keysAndValues.length; i += 2) { + T key = keysAndValues[i]; + T value = keysAndValues[i + 1]; + T old = map.put(key, value); + assertWithMessage("Key %s set to %s and %s", key, value, old).that(old).isNull(); + } + return map; + } + + private static Entry entry(T key, T value) { + return new AbstractMap.SimpleImmutableEntry<>(key, value); + } } diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java index 52632580c3e8..ac09593bac1d 100644 --- a/android/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java +++ b/android/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java @@ -17,11 +17,13 @@ package com.google.common.collect; import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.ImmutableMultimap.Builder; import com.google.common.collect.testing.SampleElements; import com.google.common.collect.testing.SampleElements.Unhashables; import com.google.common.collect.testing.UnhashableObject; import com.google.common.testing.EqualsTester; +import com.google.common.testing.NullPointerTester; import java.util.Arrays; import java.util.Map.Entry; import junit.framework.TestCase; @@ -124,4 +126,13 @@ public void testEquals() { ImmutableMultimap.of(1, "a", 2, "b"), ImmutableMultimap.of(2, "b", 1, "a")) .testEquals(); } + + @GwtIncompatible // reflection + public void testNulls() throws Exception { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicStaticMethods(ImmutableMultimap.class); + tester.ignore(ImmutableListMultimap.class.getMethod("get", Object.class)); + tester.testAllPublicInstanceMethods(ImmutableMultimap.of()); + tester.testAllPublicInstanceMethods(ImmutableMultimap.of("a", 1)); + } } diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java index 5ca1f586199d..4c2bf3f92a83 100644 --- a/android/guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java +++ b/android/guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java @@ -312,6 +312,7 @@ public void testMultipleBoundedAboveRanges() { assertEquals(expectedComplement, rangeSet.complement()); } + @SuppressWarnings("DoNotCall") public void testAddUnsupported() { RangeSet rangeSet = ImmutableRangeSet.builder() @@ -327,6 +328,7 @@ public void testAddUnsupported() { } } + @SuppressWarnings("DoNotCall") public void testAddAllUnsupported() { RangeSet rangeSet = ImmutableRangeSet.builder() @@ -342,6 +344,7 @@ public void testAddAllUnsupported() { } } + @SuppressWarnings("DoNotCall") public void testRemoveUnsupported() { RangeSet rangeSet = ImmutableRangeSet.builder() @@ -357,6 +360,7 @@ public void testRemoveUnsupported() { } } + @SuppressWarnings("DoNotCall") public void testRemoveAllUnsupported() { RangeSet rangeSet = ImmutableRangeSet.builder() diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java index 8690e948bd15..33d4ec1aa356 100644 --- a/android/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java +++ b/android/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java @@ -29,6 +29,7 @@ import com.google.common.collect.testing.google.TestStringSetMultimapGenerator; import com.google.common.collect.testing.google.UnmodifiableCollectionTests; import com.google.common.testing.EqualsTester; +import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; import java.util.Arrays; import java.util.Collection; @@ -592,4 +593,13 @@ private ImmutableSetMultimap createMultimap() { .put("foo", 3) .build(); } + + @GwtIncompatible // reflection + public void testNulls() throws Exception { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicStaticMethods(ImmutableSetMultimap.class); + tester.ignore(ImmutableSetMultimap.class.getMethod("get", Object.class)); + tester.testAllPublicInstanceMethods(ImmutableSetMultimap.of()); + tester.testAllPublicInstanceMethods(ImmutableSetMultimap.of("a", 1)); + } } diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java index 9f3a7706cd86..4a9178b4af6e 100644 --- a/android/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java +++ b/android/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java @@ -56,6 +56,7 @@ * @author Jared Levy */ @GwtCompatible(emulated = true) +@SuppressWarnings("AlwaysThrows") public class ImmutableSortedMapTest extends TestCase { // TODO: Avoid duplicating code in ImmutableMapTest @@ -482,6 +483,136 @@ public void testOf() { 3, "two", 2); + assertMapEquals( + ImmutableSortedMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6), + "five", + 5, + "four", + 4, + "one", + 1, + "six", + 6, + "three", + 3, + "two", + 2); + assertMapEquals( + ImmutableSortedMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7), + "five", + 5, + "four", + 4, + "one", + 1, + "seven", + 7, + "six", + 6, + "three", + 3, + "two", + 2); + assertMapEquals( + ImmutableSortedMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7, + "eight", 8), + "eight", + 8, + "five", + 5, + "four", + 4, + "one", + 1, + "seven", + 7, + "six", + 6, + "three", + 3, + "two", + 2); + assertMapEquals( + ImmutableSortedMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7, + "eight", 8, + "nine", 9), + "eight", + 8, + "five", + 5, + "four", + 4, + "nine", + 9, + "one", + 1, + "seven", + 7, + "six", + 6, + "three", + 3, + "two", + 2); + assertMapEquals( + ImmutableSortedMap.of( + "one", 1, + "two", 2, + "three", 3, + "four", 4, + "five", 5, + "six", 6, + "seven", 7, + "eight", 8, + "nine", 9, + "ten", 10), + "eight", + 8, + "five", + 5, + "four", + 4, + "nine", + 9, + "one", + 1, + "seven", + 7, + "six", + 6, + "ten", + 10, + "three", + 3, + "two", + 2); } public void testOfNullKey() { @@ -745,12 +876,11 @@ public void testNullValuesInCopyOfEntries() { } private static void assertMapEquals(Map map, Object... alternatingKeysAndValues) { - assertEquals(map.size(), alternatingKeysAndValues.length / 2); - int i = 0; - for (Entry entry : map.entrySet()) { - assertEquals(alternatingKeysAndValues[i++], entry.getKey()); - assertEquals(alternatingKeysAndValues[i++], entry.getValue()); + Map expected = new LinkedHashMap<>(); + for (int i = 0; i < alternatingKeysAndValues.length; i += 2) { + expected.put(alternatingKeysAndValues[i], alternatingKeysAndValues[i + 1]); } + assertThat(map).containsExactlyEntriesIn(expected).inOrder(); } private static class IntHolder implements Serializable { diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java index 2ebff40fe97a..ea0e3a8d16bc 100644 --- a/android/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java +++ b/android/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java @@ -915,7 +915,7 @@ public void testLegacyComparable_builder_reverse() { assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_BACKWARD, set)); } - @SuppressWarnings({"deprecation", "static-access"}) + @SuppressWarnings({"deprecation", "static-access", "DoNotCall"}) public void testBuilderMethod() { try { ImmutableSortedSet.builder(); diff --git a/android/guava-tests/test/com/google/common/collect/IteratorsTest.java b/android/guava-tests/test/com/google/common/collect/IteratorsTest.java index 15f7ccc2040a..e71c8bd51eea 100644 --- a/android/guava-tests/test/com/google/common/collect/IteratorsTest.java +++ b/android/guava-tests/test/com/google/common/collect/IteratorsTest.java @@ -74,6 +74,7 @@ public static Test suite() { return suite; } + @SuppressWarnings("DoNotCall") public void testEmptyIterator() { Iterator iterator = Iterators.emptyIterator(); assertFalse(iterator.hasNext()); @@ -89,6 +90,7 @@ public void testEmptyIterator() { } } + @SuppressWarnings("DoNotCall") public void testEmptyListIterator() { ListIterator iterator = Iterators.emptyListIterator(); assertFalse(iterator.hasNext()); @@ -1119,6 +1121,7 @@ public void testForArrayEmpty() { } } + @SuppressWarnings("DoNotCall") public void testForArrayTypical() { String[] array = {"foo", "bar"}; Iterator iterator = Iterators.forArray(array); @@ -1205,6 +1208,7 @@ public void testForEnumerationEmpty() { } } + @SuppressWarnings("DoNotCall") public void testForEnumerationSingleton() { Enumeration enumer = enumerate(1); Iterator iter = Iterators.forEnumeration(enumer); diff --git a/android/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java b/android/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java index d57d5c044c87..b0d48f0f4d66 100644 --- a/android/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java +++ b/android/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java @@ -35,6 +35,7 @@ import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringListMultimapGenerator; import com.google.common.testing.EqualsTester; +import com.google.common.testing.NullPointerTester; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -496,4 +497,13 @@ public void testEquals() { LinkedListMultimap.create(), LinkedListMultimap.create(), LinkedListMultimap.create(1)) .testEquals(); } + + @GwtIncompatible // reflection + public void testNulls() throws Exception { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicStaticMethods(LinkedListMultimap.class); + tester.ignore(LinkedListMultimap.class.getMethod("get", Object.class)); + tester.ignore(LinkedListMultimap.class.getMethod("removeAll", Object.class)); + tester.testAllPublicInstanceMethods(LinkedListMultimap.create()); + } } diff --git a/android/guava-tests/test/com/google/common/collect/ListsTest.java b/android/guava-tests/test/com/google/common/collect/ListsTest.java index ef90e5493f96..33736d6d8116 100644 --- a/android/guava-tests/test/com/google/common/collect/ListsTest.java +++ b/android/guava-tests/test/com/google/common/collect/ListsTest.java @@ -619,14 +619,14 @@ public void testCartesianProduct_contains() { public void testCartesianProduct_indexOf() { List> actual = Lists.cartesianProduct(list(1, 2), list(3, 4)); - assertEquals(actual.indexOf(list(1, 3)), 0); - assertEquals(actual.indexOf(list(1, 4)), 1); - assertEquals(actual.indexOf(list(2, 3)), 2); - assertEquals(actual.indexOf(list(2, 4)), 3); - assertEquals(actual.indexOf(list(3, 1)), -1); - - assertEquals(actual.indexOf(list(1)), -1); - assertEquals(actual.indexOf(list(1, 1, 1)), -1); + assertEquals(0, actual.indexOf(list(1, 3))); + assertEquals(1, actual.indexOf(list(1, 4))); + assertEquals(2, actual.indexOf(list(2, 3))); + assertEquals(3, actual.indexOf(list(2, 4))); + assertEquals(-1, actual.indexOf(list(3, 1))); + + assertEquals(-1, actual.indexOf(list(1))); + assertEquals(-1, actual.indexOf(list(1, 1, 1))); } public void testCartesianProduct_lastIndexOf() { diff --git a/android/guava-tests/test/com/google/common/collect/MapMakerTest.java b/android/guava-tests/test/com/google/common/collect/MapMakerTest.java index 4b54f0dd5350..9669ded7c302 100644 --- a/android/guava-tests/test/com/google/common/collect/MapMakerTest.java +++ b/android/guava-tests/test/com/google/common/collect/MapMakerTest.java @@ -57,31 +57,28 @@ public T apply(T key) { * anywhere else */ - /** Tests for the builder. */ - public static class MakerTest extends TestCase { - public void testInitialCapacity_negative() { - MapMaker maker = new MapMaker(); - try { - maker.initialCapacity(-1); - fail(); - } catch (IllegalArgumentException expected) { - } + public void testInitialCapacity_negative() { + MapMaker maker = new MapMaker(); + try { + maker.initialCapacity(-1); + fail(); + } catch (IllegalArgumentException expected) { } + } - // TODO(cpovirk): enable when ready - public void xtestInitialCapacity_setTwice() { - MapMaker maker = new MapMaker().initialCapacity(16); - try { - // even to the same value is not allowed - maker.initialCapacity(16); - fail(); - } catch (IllegalArgumentException expected) { - } + // TODO(cpovirk): enable when ready (apparently after a change to our GWT emulation) + public void xtestInitialCapacity_setTwice() { + MapMaker maker = new MapMaker().initialCapacity(16); + try { + // even to the same value is not allowed + maker.initialCapacity(16); + fail(); + } catch (IllegalStateException expected) { } + } - public void testReturnsPlainConcurrentHashMapWhenPossible() { - Map map = new MapMaker().initialCapacity(5).makeMap(); - assertTrue(map instanceof ConcurrentHashMap); - } + public void testReturnsPlainConcurrentHashMapWhenPossible() { + Map map = new MapMaker().initialCapacity(5).makeMap(); + assertTrue(map instanceof ConcurrentHashMap); } } diff --git a/android/guava-tests/test/com/google/common/collect/MapsCollectionTest.java b/android/guava-tests/test/com/google/common/collect/MapsCollectionTest.java index 54aa1aa2e65e..9aa8e66b70fb 100644 --- a/android/guava-tests/test/com/google/common/collect/MapsCollectionTest.java +++ b/android/guava-tests/test/com/google/common/collect/MapsCollectionTest.java @@ -49,10 +49,10 @@ import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; +import javax.annotation.CheckForNull; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Test suites for wrappers in {@code Maps}. @@ -561,7 +561,7 @@ static void putEntries(Map map, Entry[] entries) static final Predicate FILTER_KEYS = new Predicate() { @Override - public boolean apply(@NullableDecl String string) { + public boolean apply(@CheckForNull String string) { return !"banana".equals(string) && !"eggplant".equals(string); } }; @@ -569,7 +569,7 @@ public boolean apply(@NullableDecl String string) { static final Predicate FILTER_VALUES = new Predicate() { @Override - public boolean apply(@NullableDecl String string) { + public boolean apply(@CheckForNull String string) { return !"toast".equals(string) && !"spam".equals(string); } }; diff --git a/android/guava-tests/test/com/google/common/collect/MapsTest.java b/android/guava-tests/test/com/google/common/collect/MapsTest.java index 76394c883498..d0f98386346d 100644 --- a/android/guava-tests/test/com/google/common/collect/MapsTest.java +++ b/android/guava-tests/test/com/google/common/collect/MapsTest.java @@ -1153,8 +1153,8 @@ public void testAsConverter_isAView() throws Exception { biMap.put("two", 2); Converter converter = Maps.asConverter(biMap); - assertSame(1, converter.convert("one")); - assertSame(2, converter.convert("two")); + assertEquals((Integer) 1, converter.convert("one")); + assertEquals((Integer) 2, converter.convert("two")); try { converter.convert("three"); fail(); @@ -1163,9 +1163,9 @@ public void testAsConverter_isAView() throws Exception { biMap.put("three", 3); - assertSame(1, converter.convert("one")); - assertSame(2, converter.convert("two")); - assertSame(3, converter.convert("three")); + assertEquals((Integer) 1, converter.convert("one")); + assertEquals((Integer) 2, converter.convert("two")); + assertEquals((Integer) 3, converter.convert("three")); } public void testAsConverter_withNullMapping() throws Exception { diff --git a/android/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java b/android/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java index d81f546c55cb..b4382dbcacd0 100644 --- a/android/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java +++ b/android/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Tests for {@link Maps#transformValues}. @@ -156,7 +156,7 @@ public void testTransformEqualityOfMapsWithNullValues() { underlying, new Function() { @Override - public Boolean apply(@NullableDecl String from) { + public Boolean apply(@CheckForNull String from) { return from == null; } }); @@ -274,7 +274,7 @@ public void testTransformEntrySetContains() { underlying, new Function() { @Override - public Boolean apply(@NullableDecl Boolean from) { + public Boolean apply(@CheckForNull Boolean from) { return (from == null) ? true : null; } }); diff --git a/android/guava-tests/test/com/google/common/collect/MapsTransformValuesUnmodifiableIteratorTest.java b/android/guava-tests/test/com/google/common/collect/MapsTransformValuesUnmodifiableIteratorTest.java index 81a2d935bdbf..10739513f0c1 100644 --- a/android/guava-tests/test/com/google/common/collect/MapsTransformValuesUnmodifiableIteratorTest.java +++ b/android/guava-tests/test/com/google/common/collect/MapsTransformValuesUnmodifiableIteratorTest.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Tests for {@link Maps#transformValues} when the backing map's views have iterators that don't @@ -232,7 +232,7 @@ public void testTransformEqualityOfMapsWithNullValues() { underlying, new Function() { @Override - public Boolean apply(@NullableDecl String from) { + public Boolean apply(@CheckForNull String from) { return from == null; } }); @@ -350,7 +350,7 @@ public void testTransformEntrySetContains() { underlying, new Function() { @Override - public Boolean apply(@NullableDecl Boolean from) { + public Boolean apply(@CheckForNull Boolean from) { return (from == null) ? true : null; } }); diff --git a/android/guava-tests/test/com/google/common/collect/MultimapsTest.java b/android/guava-tests/test/com/google/common/collect/MultimapsTest.java index 1a8f84e5ab9e..02ea574bbc50 100644 --- a/android/guava-tests/test/com/google/common/collect/MultimapsTest.java +++ b/android/guava-tests/test/com/google/common/collect/MultimapsTest.java @@ -55,8 +55,8 @@ import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeSet; +import javax.annotation.CheckForNull; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Unit test for {@code Multimaps}. @@ -267,8 +267,8 @@ private static void checkUnmodifiableMultimap( private static void checkUnmodifiableMultimap( Multimap multimap, boolean permitsDuplicates, - @NullableDecl String nullKey, - @NullableDecl Integer nullValue) { + @CheckForNull String nullKey, + @CheckForNull Integer nullValue) { Multimap unmodifiable = prepareUnmodifiableTests(multimap, permitsDuplicates, nullKey, nullValue); @@ -297,8 +297,8 @@ private static void checkUnmodifiableMultimap( private static Multimap prepareUnmodifiableTests( Multimap multimap, boolean permitsDuplicates, - @NullableDecl String nullKey, - @NullableDecl Integer nullValue) { + @CheckForNull String nullKey, + @CheckForNull Integer nullValue) { multimap.clear(); multimap.put("foo", 1); multimap.put("foo", 2); @@ -610,7 +610,8 @@ public void testNewMultimap() { assertEquals("[3, 1, 4]", ummodifiable.get(Color.BLUE).toString()); Collection collection = multimap.get(Color.BLUE); - assertEquals(collection, collection); + // Explicitly call `equals`; `assertEquals` might return fast + assertTrue(collection.equals(collection)); assertFalse(multimap.keySet() instanceof SortedSet); assertFalse(multimap.asMap() instanceof SortedMap); diff --git a/android/guava-tests/test/com/google/common/collect/OrderingTest.java b/android/guava-tests/test/com/google/common/collect/OrderingTest.java index b449a29ee34c..7c4acc943159 100644 --- a/android/guava-tests/test/com/google/common/collect/OrderingTest.java +++ b/android/guava-tests/test/com/google/common/collect/OrderingTest.java @@ -40,8 +40,8 @@ import java.util.List; import java.util.Random; import java.util.RandomAccess; +import javax.annotation.CheckForNull; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Unit tests for {@code Ordering}. @@ -1030,7 +1030,7 @@ Scenario mutate(final Scenario scenario) { scenario.ordering.onResultOf( new Function() { @Override - public T apply(@NullableDecl Integer from) { + public T apply(@CheckForNull Integer from) { return scenario.strictlyOrderedList.get(from); } }); diff --git a/android/guava-tests/test/com/google/common/collect/RangeTest.java b/android/guava-tests/test/com/google/common/collect/RangeTest.java index 9a2cd74161a8..e8578bfd199b 100644 --- a/android/guava-tests/test/com/google/common/collect/RangeTest.java +++ b/android/guava-tests/test/com/google/common/collect/RangeTest.java @@ -20,6 +20,7 @@ import static com.google.common.collect.BoundType.OPEN; import static com.google.common.collect.DiscreteDomain.integers; import static com.google.common.testing.SerializableTester.reserializeAndAssert; +import static com.google.common.truth.Truth.assertThat; import static java.util.Arrays.asList; import com.google.common.annotations.GwtCompatible; @@ -349,11 +350,14 @@ public void testIntersection_empty() { range.intersection(Range.open(3, 5)); fail(); } catch (IllegalArgumentException expected) { + // TODO(kevinb): convert the rest of this file to Truth someday + assertThat(expected).hasMessageThat().contains("connected"); } try { range.intersection(Range.closed(0, 2)); fail(); } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().contains("connected"); } } @@ -368,11 +372,13 @@ public void testIntersection_deFactoEmpty() { range.intersection(Range.lessThan(3)); fail(); } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().contains("connected"); } try { range.intersection(Range.greaterThan(4)); fail(); } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().contains("connected"); } range = Range.closed(3, 4); @@ -395,11 +401,13 @@ public void testIntersection_singleton() { range.intersection(Range.atLeast(4)); fail(); } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().contains("connected"); } try { range.intersection(Range.atMost(2)); fail(); } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().contains("connected"); } } @@ -411,6 +419,7 @@ public void testIntersection_general() { range.intersection(Range.closed(0, 2)); fail(); } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().contains("connected"); } // adjacent below @@ -451,6 +460,7 @@ public void testIntersection_general() { range.intersection(Range.closed(10, 12)); fail(); } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessageThat().contains("connected"); } } diff --git a/android/guava-tests/test/com/google/common/collect/RegularImmutableAsListTest.java b/android/guava-tests/test/com/google/common/collect/RegularImmutableAsListTest.java index b6c2358c590a..b0f9e16e4327 100644 --- a/android/guava-tests/test/com/google/common/collect/RegularImmutableAsListTest.java +++ b/android/guava-tests/test/com/google/common/collect/RegularImmutableAsListTest.java @@ -30,7 +30,8 @@ public class RegularImmutableAsListTest extends TestCase { */ public void testDoesntCheckForNull() { ImmutableSet set = ImmutableSet.of(1, 2, 3); - new RegularImmutableAsList(set, new Object[] {null, null, null}); + ImmutableList unused = + new RegularImmutableAsList(set, new Object[] {null, null, null}); // shouldn't throw! } } diff --git a/android/guava-tests/test/com/google/common/collect/SetOperationsTest.java b/android/guava-tests/test/com/google/common/collect/SetOperationsTest.java index 7a1ec3a6590c..9a26f29457b3 100644 --- a/android/guava-tests/test/com/google/common/collect/SetOperationsTest.java +++ b/android/guava-tests/test/com/google/common/collect/SetOperationsTest.java @@ -291,92 +291,90 @@ protected Set create(String[] elements) { .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES) .createTestSuite()); - suite.addTestSuite(MoreTests.class); + suite.addTestSuite(SetOperationsTest.class); return suite; } - public static class MoreTests extends TestCase { - Set friends; - Set enemies; - - @Override - public void setUp() { - friends = Sets.newHashSet("Tom", "Joe", "Dave"); - enemies = Sets.newHashSet("Dick", "Harry", "Tom"); - } - - public void testUnion() { - Set all = Sets.union(friends, enemies); - assertEquals(5, all.size()); - - ImmutableSet immut = Sets.union(friends, enemies).immutableCopy(); - HashSet mut = Sets.union(friends, enemies).copyInto(new HashSet()); - - enemies.add("Buck"); - assertEquals(6, all.size()); - assertEquals(5, immut.size()); - assertEquals(5, mut.size()); - } - - public void testIntersection() { - Set friends = Sets.newHashSet("Tom", "Joe", "Dave"); - Set enemies = Sets.newHashSet("Dick", "Harry", "Tom"); - - Set frenemies = Sets.intersection(friends, enemies); - assertEquals(1, frenemies.size()); - - ImmutableSet immut = Sets.intersection(friends, enemies).immutableCopy(); - HashSet mut = Sets.intersection(friends, enemies).copyInto(new HashSet()); - - enemies.add("Joe"); - assertEquals(2, frenemies.size()); - assertEquals(1, immut.size()); - assertEquals(1, mut.size()); - } - - public void testDifference() { - Set friends = Sets.newHashSet("Tom", "Joe", "Dave"); - Set enemies = Sets.newHashSet("Dick", "Harry", "Tom"); - - Set goodFriends = Sets.difference(friends, enemies); - assertEquals(2, goodFriends.size()); - - ImmutableSet immut = Sets.difference(friends, enemies).immutableCopy(); - HashSet mut = Sets.difference(friends, enemies).copyInto(new HashSet()); - - enemies.add("Dave"); - assertEquals(1, goodFriends.size()); - assertEquals(2, immut.size()); - assertEquals(2, mut.size()); - } - - public void testSymmetricDifference() { - Set friends = Sets.newHashSet("Tom", "Joe", "Dave"); - Set enemies = Sets.newHashSet("Dick", "Harry", "Tom"); - - Set symmetricDifferenceFriendsFirst = Sets.symmetricDifference(friends, enemies); - assertEquals(4, symmetricDifferenceFriendsFirst.size()); - - Set symmetricDifferenceEnemiesFirst = Sets.symmetricDifference(enemies, friends); - assertEquals(4, symmetricDifferenceEnemiesFirst.size()); - - assertEquals(symmetricDifferenceFriendsFirst, symmetricDifferenceEnemiesFirst); - - ImmutableSet immut = Sets.symmetricDifference(friends, enemies).immutableCopy(); - HashSet mut = - Sets.symmetricDifference(friends, enemies).copyInto(new HashSet()); - - enemies.add("Dave"); - assertEquals(3, symmetricDifferenceFriendsFirst.size()); - assertEquals(4, immut.size()); - assertEquals(4, mut.size()); - - immut = Sets.symmetricDifference(enemies, friends).immutableCopy(); - mut = Sets.symmetricDifference(enemies, friends).copyInto(new HashSet()); - friends.add("Harry"); - assertEquals(2, symmetricDifferenceEnemiesFirst.size()); - assertEquals(3, immut.size()); - assertEquals(3, mut.size()); - } + Set friends; + Set enemies; + + @Override + public void setUp() { + friends = Sets.newHashSet("Tom", "Joe", "Dave"); + enemies = Sets.newHashSet("Dick", "Harry", "Tom"); + } + + public void testUnion() { + Set all = Sets.union(friends, enemies); + assertEquals(5, all.size()); + + ImmutableSet immut = Sets.union(friends, enemies).immutableCopy(); + HashSet mut = Sets.union(friends, enemies).copyInto(new HashSet()); + + enemies.add("Buck"); + assertEquals(6, all.size()); + assertEquals(5, immut.size()); + assertEquals(5, mut.size()); + } + + public void testIntersection() { + Set friends = Sets.newHashSet("Tom", "Joe", "Dave"); + Set enemies = Sets.newHashSet("Dick", "Harry", "Tom"); + + Set frenemies = Sets.intersection(friends, enemies); + assertEquals(1, frenemies.size()); + + ImmutableSet immut = Sets.intersection(friends, enemies).immutableCopy(); + HashSet mut = Sets.intersection(friends, enemies).copyInto(new HashSet()); + + enemies.add("Joe"); + assertEquals(2, frenemies.size()); + assertEquals(1, immut.size()); + assertEquals(1, mut.size()); + } + + public void testDifference() { + Set friends = Sets.newHashSet("Tom", "Joe", "Dave"); + Set enemies = Sets.newHashSet("Dick", "Harry", "Tom"); + + Set goodFriends = Sets.difference(friends, enemies); + assertEquals(2, goodFriends.size()); + + ImmutableSet immut = Sets.difference(friends, enemies).immutableCopy(); + HashSet mut = Sets.difference(friends, enemies).copyInto(new HashSet()); + + enemies.add("Dave"); + assertEquals(1, goodFriends.size()); + assertEquals(2, immut.size()); + assertEquals(2, mut.size()); + } + + public void testSymmetricDifference() { + Set friends = Sets.newHashSet("Tom", "Joe", "Dave"); + Set enemies = Sets.newHashSet("Dick", "Harry", "Tom"); + + Set symmetricDifferenceFriendsFirst = Sets.symmetricDifference(friends, enemies); + assertEquals(4, symmetricDifferenceFriendsFirst.size()); + + Set symmetricDifferenceEnemiesFirst = Sets.symmetricDifference(enemies, friends); + assertEquals(4, symmetricDifferenceEnemiesFirst.size()); + + assertEquals(symmetricDifferenceFriendsFirst, symmetricDifferenceEnemiesFirst); + + ImmutableSet immut = Sets.symmetricDifference(friends, enemies).immutableCopy(); + HashSet mut = + Sets.symmetricDifference(friends, enemies).copyInto(new HashSet()); + + enemies.add("Dave"); + assertEquals(3, symmetricDifferenceFriendsFirst.size()); + assertEquals(4, immut.size()); + assertEquals(4, mut.size()); + + immut = Sets.symmetricDifference(enemies, friends).immutableCopy(); + mut = Sets.symmetricDifference(enemies, friends).copyInto(new HashSet()); + friends.add("Harry"); + assertEquals(2, symmetricDifferenceEnemiesFirst.size()); + assertEquals(3, immut.size()); + assertEquals(3, mut.size()); } } diff --git a/android/guava-tests/test/com/google/common/collect/SetsTest.java b/android/guava-tests/test/com/google/common/collect/SetsTest.java index 8aa8d8312452..d7799cec0c8a 100644 --- a/android/guava-tests/test/com/google/common/collect/SetsTest.java +++ b/android/guava-tests/test/com/google/common/collect/SetsTest.java @@ -73,10 +73,10 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.CopyOnWriteArraySet; +import javax.annotation.CheckForNull; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Unit test for {@code Sets}. @@ -325,6 +325,7 @@ private enum SomeEnum { D } + @SuppressWarnings("DoNotCall") public void testImmutableEnumSet() { Set units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B); @@ -1076,7 +1077,7 @@ private static void verifyLinkedHashSetContents( * same as the given comparator. */ private static void verifySortedSetContents( - SortedSet set, Iterable iterable, @NullableDecl Comparator comparator) { + SortedSet set, Iterable iterable, @CheckForNull Comparator comparator) { assertSame(comparator, set.comparator()); verifySetContents(set, iterable); } diff --git a/android/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java b/android/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java index 830536dfc5db..02ab44b9f5c3 100644 --- a/android/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java +++ b/android/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java @@ -28,10 +28,10 @@ import java.util.Iterator; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import javax.annotation.CheckForNull; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Unit test for {@link AbstractMultiset}. @@ -106,7 +106,7 @@ public void clear() { } @Override - public int count(@NullableDecl Object element) { + public int count(@CheckForNull Object element) { for (Entry entry : entrySet()) { if (Objects.equal(entry.getElement(), element)) { return entry.getCount(); @@ -116,7 +116,7 @@ public int count(@NullableDecl Object element) { } @Override - public int add(@NullableDecl E element, int occurrences) { + public int add(@CheckForNull E element, int occurrences) { checkArgument(occurrences >= 0); Integer frequency = backingMap.get(element); if (frequency == null) { diff --git a/android/guava-tests/test/com/google/common/collect/SynchronizedDequeTest.java b/android/guava-tests/test/com/google/common/collect/SynchronizedDequeTest.java index 0a11b27ab9ba..1df6aa1bffd1 100644 --- a/android/guava-tests/test/com/google/common/collect/SynchronizedDequeTest.java +++ b/android/guava-tests/test/com/google/common/collect/SynchronizedDequeTest.java @@ -254,6 +254,7 @@ public Iterator descendingIterator() { private static final long serialVersionUID = 0; } + @SuppressWarnings("CheckReturnValue") public void testHoldsLockOnAllOperations() { create().element(); create().offer("foo"); @@ -263,8 +264,8 @@ public void testHoldsLockOnAllOperations() { create().add("foo"); create().addAll(ImmutableList.of("foo")); create().clear(); - boolean unused = create().contains("foo"); - boolean unused2 = create().containsAll(ImmutableList.of("foo")); + create().contains("foo"); + create().containsAll(ImmutableList.of("foo")); create().equals(new ArrayDeque<>(ImmutableList.of("foo"))); create().hashCode(); create().isEmpty(); diff --git a/android/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java b/android/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java index 34d1c6f4a067..2e15eda327a5 100644 --- a/android/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java +++ b/android/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java @@ -159,11 +159,11 @@ public String toString() { */ public void testSize() { - create().size(); + int unused = create().size(); } public void testIsEmpty() { - create().isEmpty(); + boolean unused = create().isEmpty(); } public void testRemove() { @@ -216,15 +216,15 @@ public void testEntrySet() { } public void testEquals() { - create().equals(new HashMap()); + boolean unused = create().equals(new HashMap()); } public void testHashCode() { - create().hashCode(); + int unused = create().hashCode(); } public void testToString() { - create().toString(); + String unused = create().toString(); } public void testSerialization() { diff --git a/android/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java b/android/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java index 14111da785f4..3c4f1375a0ab 100644 --- a/android/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java +++ b/android/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java @@ -30,10 +30,10 @@ import java.util.Map.Entry; import java.util.RandomAccess; import java.util.Set; +import javax.annotation.CheckForNull; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Tests for {@code Synchronized#multimap}. @@ -89,7 +89,7 @@ public String toString() { } @Override - public boolean equals(@NullableDecl Object o) { + public boolean equals(@CheckForNull Object o) { assertTrue(Thread.holdsLock(mutex)); return super.equals(o); } @@ -113,25 +113,25 @@ public boolean isEmpty() { } @Override - public boolean containsKey(@NullableDecl Object key) { + public boolean containsKey(@CheckForNull Object key) { assertTrue(Thread.holdsLock(mutex)); return super.containsKey(key); } @Override - public boolean containsValue(@NullableDecl Object value) { + public boolean containsValue(@CheckForNull Object value) { assertTrue(Thread.holdsLock(mutex)); return super.containsValue(value); } @Override - public boolean containsEntry(@NullableDecl Object key, @NullableDecl Object value) { + public boolean containsEntry(@CheckForNull Object key, @CheckForNull Object value) { assertTrue(Thread.holdsLock(mutex)); return super.containsEntry(key, value); } @Override - public Set get(@NullableDecl K key) { + public Set get(@CheckForNull K key) { assertTrue(Thread.holdsLock(mutex)); /* TODO: verify that the Collection is also synchronized? */ return super.get(key); @@ -144,7 +144,7 @@ public boolean put(K key, V value) { } @Override - public boolean putAll(@NullableDecl K key, Iterable values) { + public boolean putAll(@CheckForNull K key, Iterable values) { assertTrue(Thread.holdsLock(mutex)); return super.putAll(key, values); } @@ -156,19 +156,19 @@ public boolean putAll(Multimap map) { } @Override - public Set replaceValues(@NullableDecl K key, Iterable values) { + public Set replaceValues(@CheckForNull K key, Iterable values) { assertTrue(Thread.holdsLock(mutex)); return super.replaceValues(key, values); } @Override - public boolean remove(@NullableDecl Object key, @NullableDecl Object value) { + public boolean remove(@CheckForNull Object key, @CheckForNull Object value) { assertTrue(Thread.holdsLock(mutex)); return super.remove(key, value); } @Override - public Set removeAll(@NullableDecl Object key) { + public Set removeAll(@CheckForNull Object key) { assertTrue(Thread.holdsLock(mutex)); return super.removeAll(key); } diff --git a/android/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java b/android/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java index 70ff7740a114..f7b04fe2e864 100644 --- a/android/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java +++ b/android/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java @@ -152,6 +152,7 @@ public T[] toArray(T[] array) { private static final long serialVersionUID = 0; } + @SuppressWarnings("CheckReturnValue") public void testHoldsLockOnAllOperations() { create().element(); create().offer("foo"); @@ -161,8 +162,8 @@ public void testHoldsLockOnAllOperations() { create().add("foo"); create().addAll(ImmutableList.of("foo")); create().clear(); - boolean unused = create().contains("foo"); - boolean unused2 = create().containsAll(ImmutableList.of("foo")); + create().contains("foo"); + create().containsAll(ImmutableList.of("foo")); create().equals(new ArrayDeque<>(ImmutableList.of("foo"))); create().hashCode(); create().isEmpty(); diff --git a/android/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java b/android/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java index 746ad3fc1cc6..5ffcf5d54bf7 100644 --- a/android/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java +++ b/android/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java @@ -27,9 +27,9 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; +import javax.annotation.CheckForNull; import junit.framework.Test; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Tests for {@code Synchronized#set}. @@ -82,7 +82,7 @@ public String toString() { } @Override - public boolean equals(@NullableDecl Object o) { + public boolean equals(@CheckForNull Object o) { assertTrue(Thread.holdsLock(mutex)); return super.equals(o); } @@ -94,7 +94,7 @@ public int hashCode() { } @Override - public boolean add(@NullableDecl E o) { + public boolean add(@CheckForNull E o) { assertTrue(Thread.holdsLock(mutex)); return super.add(o); } @@ -112,7 +112,7 @@ public void clear() { } @Override - public boolean contains(@NullableDecl Object o) { + public boolean contains(@CheckForNull Object o) { assertTrue(Thread.holdsLock(mutex)); return super.contains(o); } @@ -132,7 +132,7 @@ public boolean isEmpty() { /* Don't test iterator(); it may or may not hold the mutex. */ @Override - public boolean remove(@NullableDecl Object o) { + public boolean remove(@CheckForNull Object o) { assertTrue(Thread.holdsLock(mutex)); return super.remove(o); } diff --git a/android/guava-tests/test/com/google/common/collect/SynchronizedTableTest.java b/android/guava-tests/test/com/google/common/collect/SynchronizedTableTest.java index f418367eae76..e1b45443660c 100644 --- a/android/guava-tests/test/com/google/common/collect/SynchronizedTableTest.java +++ b/android/guava-tests/test/com/google/common/collect/SynchronizedTableTest.java @@ -20,7 +20,7 @@ import java.util.Collection; import java.util.Map; import java.util.Set; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; public class SynchronizedTableTest extends AbstractTableTest { private static final class TestTable implements Table, Serializable { @@ -34,7 +34,7 @@ public String toString() { } @Override - public boolean equals(@NullableDecl Object o) { + public boolean equals(@CheckForNull Object o) { assertTrue(Thread.holdsLock(mutex)); return delegate.equals(o); } @@ -58,7 +58,7 @@ public boolean isEmpty() { } @Override - public boolean containsValue(@NullableDecl Object value) { + public boolean containsValue(@CheckForNull Object value) { assertTrue(Thread.holdsLock(mutex)); return delegate.containsValue(value); } diff --git a/android/guava-tests/test/com/google/common/collect/TopKSelectorTest.java b/android/guava-tests/test/com/google/common/collect/TopKSelectorTest.java index e21f81703c30..2cebdc338b08 100644 --- a/android/guava-tests/test/com/google/common/collect/TopKSelectorTest.java +++ b/android/guava-tests/test/com/google/common/collect/TopKSelectorTest.java @@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.common.annotations.GwtCompatible; import com.google.common.math.IntMath; import com.google.common.primitives.Ints; import java.math.RoundingMode; @@ -31,6 +32,7 @@ * * @author Louis Wasserman */ +@GwtCompatible public class TopKSelectorTest extends TestCase { public void testNegativeK() { @@ -119,4 +121,13 @@ public int compare(Integer o1, Integer o2) { assertThat(top.topK()).containsExactlyElementsIn(Collections.nCopies(k, 0)); assertThat(compareCalls[0]).isAtMost(10L * n * IntMath.log2(k, RoundingMode.CEILING)); } + + public void testExceedMaxIteration() { + /* + * Bug #5692 occurred when TopKSelector called Arrays.sort incorrectly. + */ + TopKSelector top = TopKSelector.least(7); + top.offerAll(Ints.asList(5, 7, 6, 2, 4, 3, 1, 0, 0, 0, 0, 0, 0, 0)); + assertThat(top.topK()).isEqualTo(Ints.asList(0, 0, 0, 0, 0, 0, 0)); + } } diff --git a/android/guava-tests/test/com/google/common/collect/UnmodifiableIteratorTest.java b/android/guava-tests/test/com/google/common/collect/UnmodifiableIteratorTest.java index 77ecbf730362..5e474aa70f67 100644 --- a/android/guava-tests/test/com/google/common/collect/UnmodifiableIteratorTest.java +++ b/android/guava-tests/test/com/google/common/collect/UnmodifiableIteratorTest.java @@ -29,6 +29,7 @@ @GwtCompatible public class UnmodifiableIteratorTest extends TestCase { + @SuppressWarnings("DoNotCall") public void testRemove() { final String[] array = {"a", "b", "c"}; diff --git a/android/guava-tests/test/com/google/common/collect/UnmodifiableListIteratorTest.java b/android/guava-tests/test/com/google/common/collect/UnmodifiableListIteratorTest.java index c9d3068e0773..36a017d45cb3 100644 --- a/android/guava-tests/test/com/google/common/collect/UnmodifiableListIteratorTest.java +++ b/android/guava-tests/test/com/google/common/collect/UnmodifiableListIteratorTest.java @@ -29,6 +29,7 @@ */ @GwtCompatible public class UnmodifiableListIteratorTest extends TestCase { + @SuppressWarnings("DoNotCall") public void testRemove() { Iterator iterator = create(); @@ -41,6 +42,7 @@ public void testRemove() { } } + @SuppressWarnings("DoNotCall") public void testAdd() { ListIterator iterator = create(); @@ -55,6 +57,7 @@ public void testAdd() { } } + @SuppressWarnings("DoNotCall") public void testSet() { ListIterator iterator = create(); diff --git a/android/guava-tests/test/com/google/common/escape/EscapersTest.java b/android/guava-tests/test/com/google/common/escape/EscapersTest.java index 245560af61d5..442232030e0d 100644 --- a/android/guava-tests/test/com/google/common/escape/EscapersTest.java +++ b/android/guava-tests/test/com/google/common/escape/EscapersTest.java @@ -85,7 +85,7 @@ public void testAsUnicodeEscaper() throws IOException { .put('x', "".toCharArray()) .put('\uD800', "".toCharArray()) .put('\uDC00', "".toCharArray()) - .build()); + .buildOrThrow()); UnicodeEscaper unicodeEscaper = Escapers.asUnicodeEscaper(charEscaper); EscaperAsserts.assertBasic(unicodeEscaper); assertEquals("", charEscaper.escape("x\uD800\uDC00")); diff --git a/android/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java b/android/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java index 5dee7ca45303..225e55500df3 100644 --- a/android/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java +++ b/android/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java @@ -18,7 +18,7 @@ import com.google.common.testing.AbstractPackageSanityTests; import java.lang.reflect.Method; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Basic sanity tests for the entire package. @@ -41,7 +41,7 @@ private static class DummySubscriber { private final EventBus eventBus = new EventBus(); @Subscribe - public void handle(@NullableDecl Object anything) {} + public void handle(@CheckForNull Object anything) {} Subscriber toSubscriber() throws Exception { return Subscriber.create(eventBus, this, subscriberMethod()); diff --git a/android/guava-tests/test/com/google/common/eventbus/StringCatcher.java b/android/guava-tests/test/com/google/common/eventbus/StringCatcher.java index 282abe11bac3..198fa2eda8ca 100644 --- a/android/guava-tests/test/com/google/common/eventbus/StringCatcher.java +++ b/android/guava-tests/test/com/google/common/eventbus/StringCatcher.java @@ -18,8 +18,8 @@ import com.google.common.collect.Lists; import java.util.List; +import javax.annotation.CheckForNull; import junit.framework.Assert; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * A simple EventSubscriber mock that records Strings. @@ -33,11 +33,11 @@ public class StringCatcher { private List events = Lists.newArrayList(); @Subscribe - public void hereHaveAString(@NullableDecl String string) { + public void hereHaveAString(@CheckForNull String string) { events.add(string); } - public void methodWithoutAnnotation(@NullableDecl String string) { + public void methodWithoutAnnotation(@CheckForNull String string) { Assert.fail("Event bus must not call methods without @Subscribe!"); } diff --git a/android/guava-tests/test/com/google/common/eventbus/outside/AbstractEventBusTest.java b/android/guava-tests/test/com/google/common/eventbus/outside/AbstractEventBusTest.java new file mode 100644 index 000000000000..f4af7a7516de --- /dev/null +++ b/android/guava-tests/test/com/google/common/eventbus/outside/AbstractEventBusTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.eventbus.outside; + +import com.google.common.eventbus.EventBus; +import junit.framework.TestCase; + +/** + * Abstract base class for tests that EventBus finds the correct subscribers. + * + *

    The actual tests are distributed among the other classes in this package based on whether they + * are annotated or abstract in the superclass. + * + *

    This test must be outside the c.g.c.eventbus package to test correctly. + * + * @author Louis Wasserman + */ +abstract class AbstractEventBusTest extends TestCase { + static final Object EVENT = new Object(); + + abstract H createSubscriber(); + + private H subscriber; + + H getSubscriber() { + return subscriber; + } + + @Override + protected void setUp() throws Exception { + subscriber = createSubscriber(); + EventBus bus = new EventBus(); + bus.register(subscriber); + bus.post(EVENT); + } + + @Override + protected void tearDown() throws Exception { + subscriber = null; + } +} diff --git a/android/guava-tests/test/com/google/common/eventbus/outside/AbstractNotAnnotatedInSuperclassTest.java b/android/guava-tests/test/com/google/common/eventbus/outside/AbstractNotAnnotatedInSuperclassTest.java new file mode 100644 index 000000000000..a391fcbad687 --- /dev/null +++ b/android/guava-tests/test/com/google/common/eventbus/outside/AbstractNotAnnotatedInSuperclassTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.eventbus.outside; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import com.google.common.eventbus.Subscribe; +import com.google.common.eventbus.outside.AbstractNotAnnotatedInSuperclassTest.SubClass; +import java.util.List; + +public class AbstractNotAnnotatedInSuperclassTest extends AbstractEventBusTest { + abstract static class SuperClass { + public abstract void overriddenInSubclassNowhereAnnotated(Object o); + + public abstract void overriddenAndAnnotatedInSubclass(Object o); + } + + static class SubClass extends SuperClass { + final List overriddenInSubclassNowhereAnnotatedEvents = Lists.newArrayList(); + final List overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList(); + + @Override + public void overriddenInSubclassNowhereAnnotated(Object o) { + overriddenInSubclassNowhereAnnotatedEvents.add(o); + } + + @Subscribe + @Override + public void overriddenAndAnnotatedInSubclass(Object o) { + overriddenAndAnnotatedInSubclassEvents.add(o); + } + } + + public void testOverriddenAndAnnotatedInSubclass() { + assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).contains(EVENT); + } + + public void testOverriddenInSubclassNowhereAnnotated() { + assertThat(getSubscriber().overriddenInSubclassNowhereAnnotatedEvents).isEmpty(); + } + + @Override + SubClass createSubscriber() { + return new SubClass(); + } +} diff --git a/android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedAndAbstractInSuperclassTest.java b/android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedAndAbstractInSuperclassTest.java new file mode 100644 index 000000000000..aea17c3b41e7 --- /dev/null +++ b/android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedAndAbstractInSuperclassTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.eventbus.outside; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import com.google.common.eventbus.Subscribe; +import com.google.common.eventbus.outside.AnnotatedAndAbstractInSuperclassTest.SubClass; +import java.util.List; + +public class AnnotatedAndAbstractInSuperclassTest extends AbstractEventBusTest { + abstract static class SuperClass { + @Subscribe + public abstract void overriddenAndAnnotatedInSubclass(Object o); + + @Subscribe + public abstract void overriddenInSubclass(Object o); + } + + static class SubClass extends SuperClass { + final List overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList(); + final List overriddenInSubclassEvents = Lists.newArrayList(); + + @Subscribe + @Override + public void overriddenAndAnnotatedInSubclass(Object o) { + overriddenAndAnnotatedInSubclassEvents.add(o); + } + + @Override + public void overriddenInSubclass(Object o) { + overriddenInSubclassEvents.add(o); + } + } + + public void testOverriddenAndAnnotatedInSubclass() { + assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).contains(EVENT); + } + + public void testOverriddenNotAnnotatedInSubclass() { + assertThat(getSubscriber().overriddenInSubclassEvents).contains(EVENT); + } + + @Override + SubClass createSubscriber() { + return new SubClass(); + } +} diff --git a/android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedNotAbstractInSuperclassTest.java b/android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedNotAbstractInSuperclassTest.java new file mode 100644 index 000000000000..3ec8ea4709f9 --- /dev/null +++ b/android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedNotAbstractInSuperclassTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.eventbus.outside; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import com.google.common.eventbus.Subscribe; +import com.google.common.eventbus.outside.AnnotatedNotAbstractInSuperclassTest.SubClass; +import java.util.List; + +public class AnnotatedNotAbstractInSuperclassTest extends AbstractEventBusTest { + static class SuperClass { + final List notOverriddenInSubclassEvents = Lists.newArrayList(); + final List overriddenNotAnnotatedInSubclassEvents = Lists.newArrayList(); + final List overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList(); + final List differentlyOverriddenNotAnnotatedInSubclassBadEvents = Lists.newArrayList(); + final List differentlyOverriddenAnnotatedInSubclassBadEvents = Lists.newArrayList(); + + @Subscribe + public void notOverriddenInSubclass(Object o) { + notOverriddenInSubclassEvents.add(o); + } + + @Subscribe + public void overriddenNotAnnotatedInSubclass(Object o) { + overriddenNotAnnotatedInSubclassEvents.add(o); + } + + @Subscribe + public void overriddenAndAnnotatedInSubclass(Object o) { + overriddenAndAnnotatedInSubclassEvents.add(o); + } + + @Subscribe + public void differentlyOverriddenNotAnnotatedInSubclass(Object o) { + // the subclass overrides this and does *not* call super.dONAIS(o) + differentlyOverriddenNotAnnotatedInSubclassBadEvents.add(o); + } + + @Subscribe + public void differentlyOverriddenAnnotatedInSubclass(Object o) { + // the subclass overrides this and does *not* call super.dOAIS(o) + differentlyOverriddenAnnotatedInSubclassBadEvents.add(o); + } + } + + static class SubClass extends SuperClass { + final List differentlyOverriddenNotAnnotatedInSubclassGoodEvents = Lists.newArrayList(); + final List differentlyOverriddenAnnotatedInSubclassGoodEvents = Lists.newArrayList(); + + @Override + public void overriddenNotAnnotatedInSubclass(Object o) { + super.overriddenNotAnnotatedInSubclass(o); + } + + @Subscribe + @Override + public void overriddenAndAnnotatedInSubclass(Object o) { + super.overriddenAndAnnotatedInSubclass(o); + } + + @Override + public void differentlyOverriddenNotAnnotatedInSubclass(Object o) { + differentlyOverriddenNotAnnotatedInSubclassGoodEvents.add(o); + } + + @Subscribe + @Override + public void differentlyOverriddenAnnotatedInSubclass(Object o) { + differentlyOverriddenAnnotatedInSubclassGoodEvents.add(o); + } + } + + public void testNotOverriddenInSubclass() { + assertThat(getSubscriber().notOverriddenInSubclassEvents).contains(EVENT); + } + + public void testOverriddenNotAnnotatedInSubclass() { + assertThat(getSubscriber().overriddenNotAnnotatedInSubclassEvents).contains(EVENT); + } + + public void testDifferentlyOverriddenNotAnnotatedInSubclass() { + assertThat(getSubscriber().differentlyOverriddenNotAnnotatedInSubclassGoodEvents) + .contains(EVENT); + assertThat(getSubscriber().differentlyOverriddenNotAnnotatedInSubclassBadEvents).isEmpty(); + } + + public void testOverriddenAndAnnotatedInSubclass() { + assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).contains(EVENT); + } + + public void testDifferentlyOverriddenAndAnnotatedInSubclass() { + assertThat(getSubscriber().differentlyOverriddenAnnotatedInSubclassGoodEvents).contains(EVENT); + assertThat(getSubscriber().differentlyOverriddenAnnotatedInSubclassBadEvents).isEmpty(); + } + + @Override + SubClass createSubscriber() { + return new SubClass(); + } +} diff --git a/android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedSubscriberFinderTests.java b/android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedSubscriberFinderTests.java deleted file mode 100644 index a1cbb594481e..000000000000 --- a/android/guava-tests/test/com/google/common/eventbus/outside/AnnotatedSubscriberFinderTests.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.eventbus.outside; - -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.collect.Lists; -import com.google.common.eventbus.EventBus; -import com.google.common.eventbus.Subscribe; -import java.util.List; -import junit.framework.TestCase; - -/** - * Test that EventBus finds the correct subscribers. - * - *

    This test must be outside the c.g.c.eventbus package to test correctly. - * - * @author Louis Wasserman - */ -public class AnnotatedSubscriberFinderTests { - - private static final Object EVENT = new Object(); - - abstract static class AbstractEventBusTest extends TestCase { - abstract H createSubscriber(); - - private H subscriber; - - H getSubscriber() { - return subscriber; - } - - @Override - protected void setUp() throws Exception { - subscriber = createSubscriber(); - EventBus bus = new EventBus(); - bus.register(subscriber); - bus.post(EVENT); - } - - @Override - protected void tearDown() throws Exception { - subscriber = null; - } - } - - /* - * We break the tests up based on whether they are annotated or abstract in the superclass. - */ - public static class BaseSubscriberFinderTest - extends AbstractEventBusTest { - static class Subscriber { - final List nonSubscriberEvents = Lists.newArrayList(); - final List subscriberEvents = Lists.newArrayList(); - - public void notASubscriber(Object o) { - nonSubscriberEvents.add(o); - } - - @Subscribe - public void subscriber(Object o) { - subscriberEvents.add(o); - } - } - - public void testNonSubscriber() { - assertThat(getSubscriber().nonSubscriberEvents).isEmpty(); - } - - public void testSubscriber() { - assertThat(getSubscriber().subscriberEvents).contains(EVENT); - } - - @Override - Subscriber createSubscriber() { - return new Subscriber(); - } - } - - public static class AnnotatedAndAbstractInSuperclassTest - extends AbstractEventBusTest { - abstract static class SuperClass { - @Subscribe - public abstract void overriddenAndAnnotatedInSubclass(Object o); - - @Subscribe - public abstract void overriddenInSubclass(Object o); - } - - static class SubClass extends SuperClass { - final List overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList(); - final List overriddenInSubclassEvents = Lists.newArrayList(); - - @Subscribe - @Override - public void overriddenAndAnnotatedInSubclass(Object o) { - overriddenAndAnnotatedInSubclassEvents.add(o); - } - - @Override - public void overriddenInSubclass(Object o) { - overriddenInSubclassEvents.add(o); - } - } - - public void testOverriddenAndAnnotatedInSubclass() { - assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).contains(EVENT); - } - - public void testOverriddenNotAnnotatedInSubclass() { - assertThat(getSubscriber().overriddenInSubclassEvents).contains(EVENT); - } - - @Override - SubClass createSubscriber() { - return new SubClass(); - } - } - - public static class AnnotatedNotAbstractInSuperclassTest - extends AbstractEventBusTest { - static class SuperClass { - final List notOverriddenInSubclassEvents = Lists.newArrayList(); - final List overriddenNotAnnotatedInSubclassEvents = Lists.newArrayList(); - final List overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList(); - final List differentlyOverriddenNotAnnotatedInSubclassBadEvents = - Lists.newArrayList(); - final List differentlyOverriddenAnnotatedInSubclassBadEvents = Lists.newArrayList(); - - @Subscribe - public void notOverriddenInSubclass(Object o) { - notOverriddenInSubclassEvents.add(o); - } - - @Subscribe - public void overriddenNotAnnotatedInSubclass(Object o) { - overriddenNotAnnotatedInSubclassEvents.add(o); - } - - @Subscribe - public void overriddenAndAnnotatedInSubclass(Object o) { - overriddenAndAnnotatedInSubclassEvents.add(o); - } - - @Subscribe - public void differentlyOverriddenNotAnnotatedInSubclass(Object o) { - // the subclass overrides this and does *not* call super.dONAIS(o) - differentlyOverriddenNotAnnotatedInSubclassBadEvents.add(o); - } - - @Subscribe - public void differentlyOverriddenAnnotatedInSubclass(Object o) { - // the subclass overrides this and does *not* call super.dOAIS(o) - differentlyOverriddenAnnotatedInSubclassBadEvents.add(o); - } - } - - static class SubClass extends SuperClass { - final List differentlyOverriddenNotAnnotatedInSubclassGoodEvents = - Lists.newArrayList(); - final List differentlyOverriddenAnnotatedInSubclassGoodEvents = Lists.newArrayList(); - - @Override - public void overriddenNotAnnotatedInSubclass(Object o) { - super.overriddenNotAnnotatedInSubclass(o); - } - - @Subscribe - @Override - public void overriddenAndAnnotatedInSubclass(Object o) { - super.overriddenAndAnnotatedInSubclass(o); - } - - @Override - public void differentlyOverriddenNotAnnotatedInSubclass(Object o) { - differentlyOverriddenNotAnnotatedInSubclassGoodEvents.add(o); - } - - @Subscribe - @Override - public void differentlyOverriddenAnnotatedInSubclass(Object o) { - differentlyOverriddenAnnotatedInSubclassGoodEvents.add(o); - } - } - - public void testNotOverriddenInSubclass() { - assertThat(getSubscriber().notOverriddenInSubclassEvents).contains(EVENT); - } - - public void testOverriddenNotAnnotatedInSubclass() { - assertThat(getSubscriber().overriddenNotAnnotatedInSubclassEvents).contains(EVENT); - } - - public void testDifferentlyOverriddenNotAnnotatedInSubclass() { - assertThat(getSubscriber().differentlyOverriddenNotAnnotatedInSubclassGoodEvents) - .contains(EVENT); - assertThat(getSubscriber().differentlyOverriddenNotAnnotatedInSubclassBadEvents).isEmpty(); - } - - public void testOverriddenAndAnnotatedInSubclass() { - assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).contains(EVENT); - } - - public void testDifferentlyOverriddenAndAnnotatedInSubclass() { - assertThat(getSubscriber().differentlyOverriddenAnnotatedInSubclassGoodEvents) - .contains(EVENT); - assertThat(getSubscriber().differentlyOverriddenAnnotatedInSubclassBadEvents).isEmpty(); - } - - @Override - SubClass createSubscriber() { - return new SubClass(); - } - } - - public static class AbstractNotAnnotatedInSuperclassTest - extends AbstractEventBusTest { - abstract static class SuperClass { - public abstract void overriddenInSubclassNowhereAnnotated(Object o); - - public abstract void overriddenAndAnnotatedInSubclass(Object o); - } - - static class SubClass extends SuperClass { - final List overriddenInSubclassNowhereAnnotatedEvents = Lists.newArrayList(); - final List overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList(); - - @Override - public void overriddenInSubclassNowhereAnnotated(Object o) { - overriddenInSubclassNowhereAnnotatedEvents.add(o); - } - - @Subscribe - @Override - public void overriddenAndAnnotatedInSubclass(Object o) { - overriddenAndAnnotatedInSubclassEvents.add(o); - } - } - - public void testOverriddenAndAnnotatedInSubclass() { - assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).contains(EVENT); - } - - public void testOverriddenInSubclassNowhereAnnotated() { - assertThat(getSubscriber().overriddenInSubclassNowhereAnnotatedEvents).isEmpty(); - } - - @Override - SubClass createSubscriber() { - return new SubClass(); - } - } - - public static class NeitherAbstractNorAnnotatedInSuperclassTest - extends AbstractEventBusTest { - static class SuperClass { - final List neitherOverriddenNorAnnotatedEvents = Lists.newArrayList(); - final List overriddenInSubclassNowhereAnnotatedEvents = Lists.newArrayList(); - final List overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList(); - - public void neitherOverriddenNorAnnotated(Object o) { - neitherOverriddenNorAnnotatedEvents.add(o); - } - - public void overriddenInSubclassNowhereAnnotated(Object o) { - overriddenInSubclassNowhereAnnotatedEvents.add(o); - } - - public void overriddenAndAnnotatedInSubclass(Object o) { - overriddenAndAnnotatedInSubclassEvents.add(o); - } - } - - static class SubClass extends SuperClass { - @Override - public void overriddenInSubclassNowhereAnnotated(Object o) { - super.overriddenInSubclassNowhereAnnotated(o); - } - - @Subscribe - @Override - public void overriddenAndAnnotatedInSubclass(Object o) { - super.overriddenAndAnnotatedInSubclass(o); - } - } - - public void testNeitherOverriddenNorAnnotated() { - assertThat(getSubscriber().neitherOverriddenNorAnnotatedEvents).isEmpty(); - } - - public void testOverriddenInSubclassNowhereAnnotated() { - assertThat(getSubscriber().overriddenInSubclassNowhereAnnotatedEvents).isEmpty(); - } - - public void testOverriddenAndAnnotatedInSubclass() { - assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).contains(EVENT); - } - - @Override - SubClass createSubscriber() { - return new SubClass(); - } - } - - public static class DeepInterfaceTest - extends AbstractEventBusTest { - interface Interface1 { - @Subscribe - void annotatedIn1(Object o); - - @Subscribe - void annotatedIn1And2(Object o); - - @Subscribe - void annotatedIn1And2AndClass(Object o); - - void declaredIn1AnnotatedIn2(Object o); - - void declaredIn1AnnotatedInClass(Object o); - - void nowhereAnnotated(Object o); - } - - interface Interface2 extends Interface1 { - @Override - @Subscribe - void declaredIn1AnnotatedIn2(Object o); - - @Override - @Subscribe - void annotatedIn1And2(Object o); - - @Override - @Subscribe - void annotatedIn1And2AndClass(Object o); - - void declaredIn2AnnotatedInClass(Object o); - - @Subscribe - void annotatedIn2(Object o); - } - - static class SubscriberClass implements Interface2 { - final List annotatedIn1Events = Lists.newArrayList(); - final List annotatedIn1And2Events = Lists.newArrayList(); - final List annotatedIn1And2AndClassEvents = Lists.newArrayList(); - final List declaredIn1AnnotatedIn2Events = Lists.newArrayList(); - final List declaredIn1AnnotatedInClassEvents = Lists.newArrayList(); - final List declaredIn2AnnotatedInClassEvents = Lists.newArrayList(); - final List annotatedIn2Events = Lists.newArrayList(); - final List nowhereAnnotatedEvents = Lists.newArrayList(); - - @Override - public void annotatedIn1(Object o) { - annotatedIn1Events.add(o); - } - - @Subscribe - @Override - public void declaredIn1AnnotatedInClass(Object o) { - declaredIn1AnnotatedInClassEvents.add(o); - } - - @Override - public void declaredIn1AnnotatedIn2(Object o) { - declaredIn1AnnotatedIn2Events.add(o); - } - - @Override - public void annotatedIn1And2(Object o) { - annotatedIn1And2Events.add(o); - } - - @Subscribe - @Override - public void annotatedIn1And2AndClass(Object o) { - annotatedIn1And2AndClassEvents.add(o); - } - - @Subscribe - @Override - public void declaredIn2AnnotatedInClass(Object o) { - declaredIn2AnnotatedInClassEvents.add(o); - } - - @Override - public void annotatedIn2(Object o) { - annotatedIn2Events.add(o); - } - - @Override - public void nowhereAnnotated(Object o) { - nowhereAnnotatedEvents.add(o); - } - } - - public void testAnnotatedIn1() { - assertThat(getSubscriber().annotatedIn1Events).contains(EVENT); - } - - public void testAnnotatedIn2() { - assertThat(getSubscriber().annotatedIn2Events).contains(EVENT); - } - - public void testAnnotatedIn1And2() { - assertThat(getSubscriber().annotatedIn1And2Events).contains(EVENT); - } - - public void testAnnotatedIn1And2AndClass() { - assertThat(getSubscriber().annotatedIn1And2AndClassEvents).contains(EVENT); - } - - public void testDeclaredIn1AnnotatedIn2() { - assertThat(getSubscriber().declaredIn1AnnotatedIn2Events).contains(EVENT); - } - - public void testDeclaredIn1AnnotatedInClass() { - assertThat(getSubscriber().declaredIn1AnnotatedInClassEvents).contains(EVENT); - } - - public void testDeclaredIn2AnnotatedInClass() { - assertThat(getSubscriber().declaredIn2AnnotatedInClassEvents).contains(EVENT); - } - - public void testNowhereAnnotated() { - assertThat(getSubscriber().nowhereAnnotatedEvents).isEmpty(); - } - - @Override - SubscriberClass createSubscriber() { - return new SubscriberClass(); - } - } -} diff --git a/android/guava-tests/test/com/google/common/eventbus/outside/BaseSubscriberFinderTest.java b/android/guava-tests/test/com/google/common/eventbus/outside/BaseSubscriberFinderTest.java new file mode 100644 index 000000000000..461fb795b07d --- /dev/null +++ b/android/guava-tests/test/com/google/common/eventbus/outside/BaseSubscriberFinderTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.eventbus.outside; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import com.google.common.eventbus.Subscribe; +import com.google.common.eventbus.outside.BaseSubscriberFinderTest.Subscriber; +import java.util.List; + +public class BaseSubscriberFinderTest extends AbstractEventBusTest { + static class Subscriber { + final List nonSubscriberEvents = Lists.newArrayList(); + final List subscriberEvents = Lists.newArrayList(); + + public void notASubscriber(Object o) { + nonSubscriberEvents.add(o); + } + + @Subscribe + public void subscriber(Object o) { + subscriberEvents.add(o); + } + } + + public void testNonSubscriber() { + assertThat(getSubscriber().nonSubscriberEvents).isEmpty(); + } + + public void testSubscriber() { + assertThat(getSubscriber().subscriberEvents).contains(EVENT); + } + + @Override + Subscriber createSubscriber() { + return new Subscriber(); + } +} diff --git a/android/guava-tests/test/com/google/common/eventbus/outside/DeepInterfaceTest.java b/android/guava-tests/test/com/google/common/eventbus/outside/DeepInterfaceTest.java new file mode 100644 index 000000000000..4fefbc12ab15 --- /dev/null +++ b/android/guava-tests/test/com/google/common/eventbus/outside/DeepInterfaceTest.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.eventbus.outside; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import com.google.common.eventbus.Subscribe; +import com.google.common.eventbus.outside.DeepInterfaceTest.SubscriberClass; +import java.util.List; + +public class DeepInterfaceTest extends AbstractEventBusTest { + interface Interface1 { + @Subscribe + void annotatedIn1(Object o); + + @Subscribe + void annotatedIn1And2(Object o); + + @Subscribe + void annotatedIn1And2AndClass(Object o); + + void declaredIn1AnnotatedIn2(Object o); + + void declaredIn1AnnotatedInClass(Object o); + + void nowhereAnnotated(Object o); + } + + interface Interface2 extends Interface1 { + @Override + @Subscribe + void declaredIn1AnnotatedIn2(Object o); + + @Override + @Subscribe + void annotatedIn1And2(Object o); + + @Override + @Subscribe + void annotatedIn1And2AndClass(Object o); + + void declaredIn2AnnotatedInClass(Object o); + + @Subscribe + void annotatedIn2(Object o); + } + + static class SubscriberClass implements Interface2 { + final List annotatedIn1Events = Lists.newArrayList(); + final List annotatedIn1And2Events = Lists.newArrayList(); + final List annotatedIn1And2AndClassEvents = Lists.newArrayList(); + final List declaredIn1AnnotatedIn2Events = Lists.newArrayList(); + final List declaredIn1AnnotatedInClassEvents = Lists.newArrayList(); + final List declaredIn2AnnotatedInClassEvents = Lists.newArrayList(); + final List annotatedIn2Events = Lists.newArrayList(); + final List nowhereAnnotatedEvents = Lists.newArrayList(); + + @Override + public void annotatedIn1(Object o) { + annotatedIn1Events.add(o); + } + + @Subscribe + @Override + public void declaredIn1AnnotatedInClass(Object o) { + declaredIn1AnnotatedInClassEvents.add(o); + } + + @Override + public void declaredIn1AnnotatedIn2(Object o) { + declaredIn1AnnotatedIn2Events.add(o); + } + + @Override + public void annotatedIn1And2(Object o) { + annotatedIn1And2Events.add(o); + } + + @Subscribe + @Override + public void annotatedIn1And2AndClass(Object o) { + annotatedIn1And2AndClassEvents.add(o); + } + + @Subscribe + @Override + public void declaredIn2AnnotatedInClass(Object o) { + declaredIn2AnnotatedInClassEvents.add(o); + } + + @Override + public void annotatedIn2(Object o) { + annotatedIn2Events.add(o); + } + + @Override + public void nowhereAnnotated(Object o) { + nowhereAnnotatedEvents.add(o); + } + } + + public void testAnnotatedIn1() { + assertThat(getSubscriber().annotatedIn1Events).contains(EVENT); + } + + public void testAnnotatedIn2() { + assertThat(getSubscriber().annotatedIn2Events).contains(EVENT); + } + + public void testAnnotatedIn1And2() { + assertThat(getSubscriber().annotatedIn1And2Events).contains(EVENT); + } + + public void testAnnotatedIn1And2AndClass() { + assertThat(getSubscriber().annotatedIn1And2AndClassEvents).contains(EVENT); + } + + public void testDeclaredIn1AnnotatedIn2() { + assertThat(getSubscriber().declaredIn1AnnotatedIn2Events).contains(EVENT); + } + + public void testDeclaredIn1AnnotatedInClass() { + assertThat(getSubscriber().declaredIn1AnnotatedInClassEvents).contains(EVENT); + } + + public void testDeclaredIn2AnnotatedInClass() { + assertThat(getSubscriber().declaredIn2AnnotatedInClassEvents).contains(EVENT); + } + + public void testNowhereAnnotated() { + assertThat(getSubscriber().nowhereAnnotatedEvents).isEmpty(); + } + + @Override + SubscriberClass createSubscriber() { + return new SubscriberClass(); + } +} diff --git a/android/guava-tests/test/com/google/common/eventbus/outside/NeitherAbstractNorAnnotatedInSuperclassTest.java b/android/guava-tests/test/com/google/common/eventbus/outside/NeitherAbstractNorAnnotatedInSuperclassTest.java new file mode 100644 index 000000000000..a2aca555b499 --- /dev/null +++ b/android/guava-tests/test/com/google/common/eventbus/outside/NeitherAbstractNorAnnotatedInSuperclassTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.eventbus.outside; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import com.google.common.eventbus.Subscribe; +import com.google.common.eventbus.outside.NeitherAbstractNorAnnotatedInSuperclassTest.SubClass; +import java.util.List; + +public class NeitherAbstractNorAnnotatedInSuperclassTest extends AbstractEventBusTest { + static class SuperClass { + final List neitherOverriddenNorAnnotatedEvents = Lists.newArrayList(); + final List overriddenInSubclassNowhereAnnotatedEvents = Lists.newArrayList(); + final List overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList(); + + public void neitherOverriddenNorAnnotated(Object o) { + neitherOverriddenNorAnnotatedEvents.add(o); + } + + public void overriddenInSubclassNowhereAnnotated(Object o) { + overriddenInSubclassNowhereAnnotatedEvents.add(o); + } + + public void overriddenAndAnnotatedInSubclass(Object o) { + overriddenAndAnnotatedInSubclassEvents.add(o); + } + } + + static class SubClass extends SuperClass { + @Override + public void overriddenInSubclassNowhereAnnotated(Object o) { + super.overriddenInSubclassNowhereAnnotated(o); + } + + @Subscribe + @Override + public void overriddenAndAnnotatedInSubclass(Object o) { + super.overriddenAndAnnotatedInSubclass(o); + } + } + + public void testNeitherOverriddenNorAnnotated() { + assertThat(getSubscriber().neitherOverriddenNorAnnotatedEvents).isEmpty(); + } + + public void testOverriddenInSubclassNowhereAnnotated() { + assertThat(getSubscriber().overriddenInSubclassNowhereAnnotatedEvents).isEmpty(); + } + + public void testOverriddenAndAnnotatedInSubclass() { + assertThat(getSubscriber().overriddenAndAnnotatedInSubclassEvents).contains(EVENT); + } + + @Override + SubClass createSubscriber() { + return new SubClass(); + } +} diff --git a/android/guava-tests/test/com/google/common/graph/MapCacheTest.java b/android/guava-tests/test/com/google/common/graph/MapCacheTest.java index f66b19b7d985..f04f010c84c9 100644 --- a/android/guava-tests/test/com/google/common/graph/MapCacheTest.java +++ b/android/guava-tests/test/com/google/common/graph/MapCacheTest.java @@ -90,25 +90,4 @@ public void testRemoveEqualKeyWithDifferentReference() { assertThat(mapCache.remove(fooReference2)).isEqualTo("bar"); assertThat(mapCache.get(fooReference1)).isNull(); } - - @Test - public void testHandleNulls() { - mapCache.put("foo", "bar"); - mapCache.put("non-null key", null); - mapCache.put(null, "non-null value"); - - assertThat(mapCache.get("foo")).isEqualTo("bar"); - assertThat(mapCache.get("non-null key")).isNull(); - assertThat(mapCache.get(null)).isEqualTo("non-null value"); - - assertThat(mapCache.containsKey("foo")).isTrue(); - assertThat(mapCache.containsKey("bar")).isFalse(); - assertThat(mapCache.containsKey("non-null key")).isTrue(); - assertThat(mapCache.containsKey(null)).isTrue(); - - // Test again - in reverse order. - assertThat(mapCache.get(null)).isEqualTo("non-null value"); - assertThat(mapCache.get("non-null key")).isNull(); - assertThat(mapCache.get("foo")).isEqualTo("bar"); - } } diff --git a/android/guava-tests/test/com/google/common/hash/BloomFilterTest.java b/android/guava-tests/test/com/google/common/hash/BloomFilterTest.java index f69b57853374..d99be0902708 100644 --- a/android/guava-tests/test/com/google/common/hash/BloomFilterTest.java +++ b/android/guava-tests/test/com/google/common/hash/BloomFilterTest.java @@ -36,8 +36,8 @@ import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; +import javax.annotation.CheckForNull; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Tests for SimpleGenericBloomFilter and derived BloomFilter views. @@ -408,7 +408,7 @@ public void funnel(Long value, PrimitiveSink into) { } @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { return (object instanceof CustomFunnel); } @@ -506,7 +506,10 @@ public void testCustomSerialization() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); bf.writeTo(out); - assertEquals(bf, BloomFilter.readFrom(new ByteArrayInputStream(out.toByteArray()), funnel)); + BloomFilter read = + BloomFilter.readFrom(new ByteArrayInputStream(out.toByteArray()), funnel); + assertThat(read).isEqualTo(bf); + assertThat(read.expectedFpp()).isGreaterThan(0); } /** diff --git a/android/guava-tests/test/com/google/common/hash/Fingerprint2011Test.java b/android/guava-tests/test/com/google/common/hash/Fingerprint2011Test.java new file mode 100644 index 000000000000..effa63291bf1 --- /dev/null +++ b/android/guava-tests/test/com/google/common/hash/Fingerprint2011Test.java @@ -0,0 +1,233 @@ +// Copyright 2011 Google Inc. All Rights Reserved. + +package com.google.common.hash; + +import static com.google.common.base.Charsets.ISO_8859_1; +import static com.google.common.base.Charsets.UTF_8; +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableSortedMap; +import com.google.common.collect.Ordering; +import com.google.common.primitives.UnsignedLong; +import java.util.Arrays; +import junit.framework.TestCase; + +/** + * Unit test for Fingerprint2011. + * + * @author kylemaddison@google.com (Kyle Maddison) + */ +public class Fingerprint2011Test extends TestCase { + + // Length of the sample string to produce + private static final int MAX_BYTES = 1000; + + // Map from sample string lengths to the fingerprint + private static final ImmutableSortedMap LENGTH_FINGERPRINTS = + new ImmutableSortedMap.Builder(Ordering.natural()) + .put(1000, 0x433109b33e13e6edL) + .put(800, 0x5f2f123bfc815f81L) + .put(640, 0x6396fc6a67293cf4L) + .put(512, 0x45c01b4934ddbbbeL) + .put(409, 0xfcd19b617551db45L) + .put(327, 0x4eee69e12854871eL) + .put(261, 0xab753446a3bbd532L) + .put(208, 0x54242fe06a291c3fL) + .put(166, 0x4f7acff7703a635bL) + .put(132, 0xa784bd0a1f22cc7fL) + .put(105, 0xf19118e187456638L) + .put(84, 0x3e2e58f9196abfe5L) + .put(67, 0xd38ae3dec0107aeaL) + .put(53, 0xea3033885868e10eL) + .put(42, 0x1394a146d0d7e04bL) + .put(33, 0x9962499315d2e8daL) + .put(26, 0x0849f5cfa85489b5L) + .put(20, 0x83b395ff19bf2171L) + .put(16, 0x9d33dd141bd55d9aL) + .put(12, 0x196248eb0b02466aL) + .put(9, 0x1cf73a50ff120336L) + .put(7, 0xb451c339457dbf51L) + .put(5, 0x681982c5e7b74064L) + .put(4, 0xc5ce47450ca6c021L) + .put(3, 0x9fcc3c3fde4d5ff7L) + .put(2, 0x090966a836e5fa4bL) + .put(1, 0x8199675ecaa6fe64L) + .put(0, 0x23ad7c904aa665e3L) + .build(); + private static final HashFunction HASH_FN = Hashing.fingerprint2011(); + + // If this test fails, all bets are off + public void testReallySimpleFingerprints() { + assertEquals(8473225671271759044L, fingerprint("test".getBytes(UTF_8))); + // 32 characters long + assertEquals(7345148637025587076L, fingerprint(Strings.repeat("test", 8).getBytes(UTF_8))); + // 256 characters long + assertEquals(4904844928629814570L, fingerprint(Strings.repeat("test", 64).getBytes(UTF_8))); + } + + public void testStringsConsistency() { + for (String s : Arrays.asList("", "some", "test", "strings", "to", "try")) { + assertEquals(HASH_FN.newHasher().putUnencodedChars(s).hash(), HASH_FN.hashUnencodedChars(s)); + } + } + + public void testUtf8() { + char[] charsA = new char[128]; + char[] charsB = new char[128]; + + for (int i = 0; i < charsA.length; i++) { + if (i < 100) { + charsA[i] = 'a'; + charsB[i] = 'a'; + } else { + // Both two-byte characters, but must be different + charsA[i] = (char) (0x0180 + i); + charsB[i] = (char) (0x0280 + i); + } + } + + String stringA = new String(charsA); + String stringB = new String(charsB); + assertThat(stringA).isNotEqualTo(stringB); + assertThat(HASH_FN.hashUnencodedChars(stringA)) + .isNotEqualTo(HASH_FN.hashUnencodedChars(stringB)); + assertThat(fingerprint(stringA.getBytes(UTF_8))) + .isNotEqualTo(fingerprint(stringB.getBytes(UTF_8))); + + // ISO 8859-1 only has 0-255 (ubyte) representation so throws away UTF-8 characters + // greater than 127 (ie with their top bit set). + // Don't attempt to do this in real code. + assertEquals( + fingerprint(stringA.getBytes(ISO_8859_1)), fingerprint(stringB.getBytes(ISO_8859_1))); + } + + public void testMumurHash64() { + byte[] bytes = "test".getBytes(UTF_8); + assertEquals( + 1618900948208871284L, Fingerprint2011.murmurHash64WithSeed(bytes, 0, bytes.length, 1)); + + bytes = "test test test".getBytes(UTF_8); + assertEquals( + UnsignedLong.valueOf("12313169684067793560").longValue(), + Fingerprint2011.murmurHash64WithSeed(bytes, 0, bytes.length, 1)); + } + + public void testPutNonChars() { + Hasher hasher = HASH_FN.newHasher(); + // Expected data is 0x0100010100000000 + hasher + .putBoolean(true) + .putBoolean(true) + .putBoolean(false) + .putBoolean(true) + .putBoolean(false) + .putBoolean(false) + .putBoolean(false) + .putBoolean(false); + final long hashCode = hasher.hash().asLong(); + + hasher = HASH_FN.newHasher(); + hasher + .putByte((byte) 0x01) + .putByte((byte) 0x01) + .putByte((byte) 0x00) + .putByte((byte) 0x01) + .putByte((byte) 0x00) + .putByte((byte) 0x00) + .putByte((byte) 0x00) + .putByte((byte) 0x00); + assertEquals(hashCode, hasher.hash().asLong()); + + hasher = HASH_FN.newHasher(); + hasher + .putChar((char) 0x0101) + .putChar((char) 0x0100) + .putChar((char) 0x0000) + .putChar((char) 0x0000); + assertEquals(hashCode, hasher.hash().asLong()); + + hasher = HASH_FN.newHasher(); + hasher.putBytes(new byte[] {0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}); + assertEquals(hashCode, hasher.hash().asLong()); + + hasher = HASH_FN.newHasher(); + hasher.putLong(0x0000000001000101L); + assertEquals(hashCode, hasher.hash().asLong()); + + hasher = HASH_FN.newHasher(); + hasher + .putShort((short) 0x0101) + .putShort((short) 0x0100) + .putShort((short) 0x0000) + .putShort((short) 0x0000); + assertEquals(hashCode, hasher.hash().asLong()); + } + + public void testHashFloatIsStable() { + // This is about the best we can do for floating-point + Hasher hasher = HASH_FN.newHasher(); + hasher.putFloat(0x01000101f).putFloat(0f); + assertEquals(0x96a4f8cc6ecbf16L, hasher.hash().asLong()); + + hasher = HASH_FN.newHasher(); + hasher.putDouble(0x0000000001000101d); + assertEquals(0xcf54171253fdc198L, hasher.hash().asLong()); + } + + /** Convenience method to compute a fingerprint on a full bytes array. */ + private static long fingerprint(byte[] bytes) { + return fingerprint(bytes, bytes.length); + } + + /** Convenience method to compute a fingerprint on a subset of a byte array. */ + private static long fingerprint(byte[] bytes, int length) { + return HASH_FN.hashBytes(bytes, 0, length).asLong(); + } + + /** + * Tests that the Java port of Fingerprint2011 provides the same results on buffers up to 800 + * bytes long as the original implementation in C++. See http://cl/106539598 + */ + public void testMultipleLengths() { + int iterations = 800; + byte[] buf = new byte[iterations * 4]; + int bufLen = 0; + long h = 0; + for (int i = 0; i < iterations; ++i) { + h ^= fingerprint(buf, i); + h = remix(h); + buf[bufLen++] = getChar(h); + + h ^= fingerprint(buf, i * i % bufLen); + h = remix(h); + buf[bufLen++] = getChar(h); + + h ^= fingerprint(buf, i * i * i % bufLen); + h = remix(h); + buf[bufLen++] = getChar(h); + + h ^= fingerprint(buf, bufLen); + h = remix(h); + buf[bufLen++] = getChar(h); + + int x0 = buf[bufLen - 1] & 0xff; + int x1 = buf[bufLen - 2] & 0xff; + int x2 = buf[bufLen - 3] & 0xff; + int x3 = buf[bufLen / 2] & 0xff; + buf[((x0 << 16) + (x1 << 8) + x2) % bufLen] ^= x3; + buf[((x1 << 16) + (x2 << 8) + x3) % bufLen] ^= i % 256; + } + assertEquals(0xeaa3b1c985261632L, h); + } + + private static long remix(long h) { + h ^= h >>> 41; + h *= 949921979; + return h; + } + + private static byte getChar(long h) { + return (byte) ('a' + ((h & 0xfffff) % 26)); + } +} diff --git a/android/guava-tests/test/com/google/common/hash/HashFunctionEnum.java b/android/guava-tests/test/com/google/common/hash/HashFunctionEnum.java index 3a98fede9540..34717477e645 100644 --- a/android/guava-tests/test/com/google/common/hash/HashFunctionEnum.java +++ b/android/guava-tests/test/com/google/common/hash/HashFunctionEnum.java @@ -32,6 +32,7 @@ enum HashFunctionEnum { MD5(Hashing.md5()), MURMUR3_128(Hashing.murmur3_128()), MURMUR3_32(Hashing.murmur3_32()), + MURMUR3_32_FIXED(Hashing.murmur3_32_fixed()), SHA1(Hashing.sha1()), SHA256(Hashing.sha256()), SHA384(Hashing.sha384()), diff --git a/android/guava-tests/test/com/google/common/hash/HashTestUtils.java b/android/guava-tests/test/com/google/common/hash/HashTestUtils.java index 8dfbdb0cdf03..9e9944b5abfb 100644 --- a/android/guava-tests/test/com/google/common/hash/HashTestUtils.java +++ b/android/guava-tests/test/com/google/common/hash/HashTestUtils.java @@ -195,8 +195,8 @@ void performAction(Random random, Iterable sinks) { int limit = pos + random.nextInt(value.length - pos + 1); for (PrimitiveSink sink : sinks) { ByteBuffer buffer = ByteBuffer.wrap(value); - buffer.position(pos); - buffer.limit(limit); + Java8Compatibility.position(buffer, pos); + Java8Compatibility.limit(buffer, limit); sink.putBytes(buffer); assertEquals(limit, buffer.limit()); assertEquals(limit, buffer.position()); diff --git a/android/guava-tests/test/com/google/common/hash/HashingTest.java b/android/guava-tests/test/com/google/common/hash/HashingTest.java index dc50299ea00f..aff5c254fac2 100644 --- a/android/guava-tests/test/com/google/common/hash/HashingTest.java +++ b/android/guava-tests/test/com/google/common/hash/HashingTest.java @@ -125,6 +125,15 @@ public void testSipHash24() { Hashing.sipHash24().toString()); } + public void testFingerprint2011() { + HashTestUtils.check2BitAvalanche(Hashing.fingerprint2011(), 100, 0.4); + HashTestUtils.checkAvalanche(Hashing.fingerprint2011(), 100, 0.4); + HashTestUtils.checkNo2BitCharacteristics(Hashing.fingerprint2011()); + HashTestUtils.checkNoFunnels(Hashing.fingerprint2011()); + HashTestUtils.assertInvariants(Hashing.fingerprint2011()); + assertEquals("Hashing.fingerprint2011()", Hashing.fingerprint2011().toString()); + } + @AndroidIncompatible // slow TODO(cpovirk): Maybe just reduce iterations under Android. public void testGoodFastHash() { for (int i = 1; i < 200; i += 17) { @@ -146,7 +155,7 @@ public void testGoodFastHash32() { // goodFastHash(128) uses Murmur3_128. Use the same epsilon bounds. public void testGoodFastHash128() { HashTestUtils.check2BitAvalanche(Hashing.goodFastHash(128), 250, 0.20); - HashTestUtils.checkAvalanche(Hashing.goodFastHash(128), 250, 0.17); + HashTestUtils.checkAvalanche(Hashing.goodFastHash(128), 500, 0.17); HashTestUtils.checkNo2BitCharacteristics(Hashing.goodFastHash(128)); HashTestUtils.checkNoFunnels(Hashing.goodFastHash(128)); HashTestUtils.assertInvariants(Hashing.goodFastHash(128)); @@ -155,7 +164,7 @@ public void testGoodFastHash128() { // goodFastHash(256) uses Murmur3_128. Use the same epsilon bounds. public void testGoodFastHash256() { HashTestUtils.check2BitAvalanche(Hashing.goodFastHash(256), 250, 0.20); - HashTestUtils.checkAvalanche(Hashing.goodFastHash(256), 250, 0.17); + HashTestUtils.checkAvalanche(Hashing.goodFastHash(256), 500, 0.17); HashTestUtils.checkNo2BitCharacteristics(Hashing.goodFastHash(256)); HashTestUtils.checkNoFunnels(Hashing.goodFastHash(256)); HashTestUtils.assertInvariants(Hashing.goodFastHash(256)); @@ -432,6 +441,9 @@ public void testHashIntVsForLoop() { .put(Hashing.murmur3_32(), EMPTY_STRING, "00000000") .put(Hashing.murmur3_32(), TQBFJOTLD, "23f74f2e") .put(Hashing.murmur3_32(), TQBFJOTLDP, "fc8bc4d5") + .put(Hashing.murmur3_32_fixed(), EMPTY_STRING, "00000000") + .put(Hashing.murmur3_32_fixed(), TQBFJOTLD, "23f74f2e") + .put(Hashing.murmur3_32_fixed(), TQBFJOTLDP, "fc8bc4d5") .put(Hashing.sha1(), EMPTY_STRING, "da39a3ee5e6b4b0d3255bfef95601890afd80709") .put(Hashing.sha1(), TQBFJOTLD, "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12") .put(Hashing.sha1(), TQBFJOTLDP, "408d94384216f890ff7a0c3528e8bed1e0b01621") @@ -489,6 +501,9 @@ public void testHashIntVsForLoop() { .put(Hashing.farmHashFingerprint64(), EMPTY_STRING, "4f40902f3b6ae19a") .put(Hashing.farmHashFingerprint64(), TQBFJOTLD, "34511b3bf383beab") .put(Hashing.farmHashFingerprint64(), TQBFJOTLDP, "737d7e5f8660653e") + .put(Hashing.fingerprint2011(), EMPTY_STRING, "e365a64a907cad23") + .put(Hashing.fingerprint2011(), TQBFJOTLD, "c9688c84e813b089") + .put(Hashing.fingerprint2011(), TQBFJOTLDP, "a714d70f1d569cd0") .build(); public void testAllHashFunctionsHaveKnownHashes() throws Exception { diff --git a/android/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java b/android/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java index de86e4bbd86b..181b2a7bb071 100644 --- a/android/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java +++ b/android/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java @@ -17,9 +17,11 @@ package com.google.common.hash; import static com.google.common.hash.Hashing.murmur3_32; +import static com.google.common.hash.Hashing.murmur3_32_fixed; import com.google.common.base.Charsets; import com.google.common.hash.HashTestUtils.HashFn; +import java.nio.charset.Charset; import java.util.Random; import junit.framework.TestCase; @@ -51,16 +53,53 @@ public void testKnownStringInputs() { -528633700, murmur3_32().hashUnencodedChars("The quick brown fox jumps over the lazy dog")); } - public void testKnownUtf8StringInputs() { - assertHash(0, murmur3_32().hashString("", Charsets.UTF_8)); - assertHash(0xcfbda5d1, murmur3_32().hashString("k", Charsets.UTF_8)); - assertHash(0xa167dbf3, murmur3_32().hashString("hell", Charsets.UTF_8)); - assertHash(0x248bfa47, murmur3_32().hashString("hello", Charsets.UTF_8)); - assertHash(0x3d41b97c, murmur3_32().hashString("http://www.google.com/", Charsets.UTF_8)); - assertHash( - 0x2e4ff723, - murmur3_32().hashString("The quick brown fox jumps over the lazy dog", Charsets.UTF_8)); - assertHash(0xfc5ba834, murmur3_32().hashString("毎月1日,毎週月曜日", Charsets.UTF_8)); + @SuppressWarnings("deprecation") + public void testKnownEncodedStringInputs() { + assertStringHash(0, "", Charsets.UTF_8); + assertStringHash(0xcfbda5d1, "k", Charsets.UTF_8); + assertStringHash(0xa167dbf3, "hell", Charsets.UTF_8); + assertStringHash(0x248bfa47, "hello", Charsets.UTF_8); + assertStringHash(0x3d41b97c, "http://www.google.com/", Charsets.UTF_8); + assertStringHash(0x2e4ff723, "The quick brown fox jumps over the lazy dog", Charsets.UTF_8); + assertStringHash(0xb5a4be05, "ABCDefGHI\u0799", Charsets.UTF_8); + assertStringHash(0xfc5ba834, "毎月1日,毎週月曜日", Charsets.UTF_8); + assertStringHash(0x8a5c3699, "surrogate pair: \uD83D\uDCB0", Charsets.UTF_8); + + assertStringHash(0, "", Charsets.UTF_16LE); + assertStringHash(0x288418e4, "k", Charsets.UTF_16LE); + assertStringHash(0x5a0cb7c3, "hell", Charsets.UTF_16LE); + assertStringHash(0xd7c31989, "hello", Charsets.UTF_16LE); + assertStringHash(0x73564d8c, "http://www.google.com/", Charsets.UTF_16LE); + assertStringHash(0xe07db09c, "The quick brown fox jumps over the lazy dog", Charsets.UTF_16LE); + assertStringHash(0xfefa3e76, "ABCDefGHI\u0799", Charsets.UTF_16LE); + assertStringHash(0x6a7be132, "毎月1日,毎週月曜日", Charsets.UTF_16LE); + assertStringHash(0x5a2d41c7, "surrogate pair: \uD83D\uDCB0", Charsets.UTF_16LE); + } + + @SuppressWarnings("deprecation") + private void assertStringHash(int expected, String string, Charset charset) { + if (allBmp(string)) { + assertHash(expected, murmur3_32().hashString(string, charset)); + } + assertHash(expected, murmur3_32_fixed().hashString(string, charset)); + assertHash(expected, murmur3_32().newHasher().putString(string, charset).hash()); + assertHash(expected, murmur3_32_fixed().newHasher().putString(string, charset).hash()); + assertHash(expected, murmur3_32().hashBytes(string.getBytes(charset))); + assertHash(expected, murmur3_32_fixed().hashBytes(string.getBytes(charset))); + assertHash(expected, murmur3_32().newHasher().putBytes(string.getBytes(charset)).hash()); + assertHash(expected, murmur3_32_fixed().newHasher().putBytes(string.getBytes(charset)).hash()); + } + + private boolean allBmp(String string) { + // Ordinarily we'd use something like i += Character.charCount(string.codePointAt(i)) here. But + // we can get away with i++ because the whole point of this method is to return false if we find + // a code point that doesn't fit in a char. + for (int i = 0; i < string.length(); i++) { + if (string.codePointAt(i) > 0xffff) { + return false; + } + } + return true; } @SuppressWarnings("deprecation") @@ -71,7 +110,7 @@ public void testSimpleStringUtf8() { } @SuppressWarnings("deprecation") - public void testStringInputsUtf8() { + public void testEncodedStringInputs() { Random rng = new Random(0); for (int z = 0; z < 100; z++) { String str; @@ -88,9 +127,16 @@ public void testStringInputsUtf8() { builder.appendCodePoint(codePoints[i]); } str = builder.toString(); + HashCode hashUtf8 = murmur3_32().hashBytes(str.getBytes(Charsets.UTF_8)); + assertEquals( + hashUtf8, murmur3_32().newHasher().putBytes(str.getBytes(Charsets.UTF_8)).hash()); + assertEquals(hashUtf8, murmur3_32().hashString(str, Charsets.UTF_8)); + assertEquals(hashUtf8, murmur3_32().newHasher().putString(str, Charsets.UTF_8).hash()); + HashCode hashUtf16 = murmur3_32().hashBytes(str.getBytes(Charsets.UTF_16)); assertEquals( - murmur3_32().hashBytes(str.getBytes(Charsets.UTF_8)), - murmur3_32().hashString(str, Charsets.UTF_8)); + hashUtf16, murmur3_32().newHasher().putBytes(str.getBytes(Charsets.UTF_16)).hash()); + assertEquals(hashUtf16, murmur3_32().hashString(str, Charsets.UTF_16)); + assertEquals(hashUtf16, murmur3_32().newHasher().putString(str, Charsets.UTF_16).hash()); } } @@ -138,8 +184,12 @@ public void testInvalidUnicodeHashString() { assertEquals( murmur3_32().hashBytes(str.getBytes(Charsets.UTF_8)), murmur3_32().hashString(str, Charsets.UTF_8)); + assertEquals( + murmur3_32_fixed().hashBytes(str.getBytes(Charsets.UTF_8)), + murmur3_32().hashString(str, Charsets.UTF_8)); } + @SuppressWarnings("deprecation") public void testInvalidUnicodeHasherPutString() { String str = new String( @@ -147,5 +197,8 @@ public void testInvalidUnicodeHasherPutString() { assertEquals( murmur3_32().hashBytes(str.getBytes(Charsets.UTF_8)), murmur3_32().newHasher().putString(str, Charsets.UTF_8).hash()); + assertEquals( + murmur3_32_fixed().hashBytes(str.getBytes(Charsets.UTF_8)), + murmur3_32_fixed().newHasher().putString(str, Charsets.UTF_8).hash()); } } diff --git a/android/guava-tests/test/com/google/common/io/BaseEncodingTest.java b/android/guava-tests/test/com/google/common/io/BaseEncodingTest.java index 832fb0713fa9..c2fdf025731a 100644 --- a/android/guava-tests/test/com/google/common/io/BaseEncodingTest.java +++ b/android/guava-tests/test/com/google/common/io/BaseEncodingTest.java @@ -35,8 +35,8 @@ import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; +import javax.annotation.CheckForNull; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Tests for {@code BaseEncoding}. @@ -405,7 +405,7 @@ private static void assertFailsToDecode(BaseEncoding encoding, String cannotDeco } private static void assertFailsToDecode( - BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage) { + BaseEncoding encoding, String cannotDecode, @CheckForNull String expectedMessage) { // We use this somewhat weird pattern with an enum for each assertion we want to make as a way // of dealing with the fact that one of the assertions is @GwtIncompatible but we don't want to // have to have duplicate @GwtIncompatible test methods just to make that assertion. @@ -419,7 +419,7 @@ enum AssertFailsToDecodeStrategy { DECODING_STREAM { @Override void assertFailsToDecode( - BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage) { + BaseEncoding encoding, String cannotDecode, @CheckForNull String expectedMessage) { // Regression test for case where DecodingException was swallowed by default implementation // of // InputStream.read(byte[], int, int) @@ -440,14 +440,14 @@ void assertFailsToDecode( CAN_DECODE { @Override void assertFailsToDecode( - BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage) { + BaseEncoding encoding, String cannotDecode, @CheckForNull String expectedMessage) { assertFalse(encoding.canDecode(cannotDecode)); } }, DECODE { @Override void assertFailsToDecode( - BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage) { + BaseEncoding encoding, String cannotDecode, @CheckForNull String expectedMessage) { try { encoding.decode(cannotDecode); fail("Expected IllegalArgumentException"); @@ -461,7 +461,7 @@ void assertFailsToDecode( DECODE_CHECKED { @Override void assertFailsToDecode( - BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage) { + BaseEncoding encoding, String cannotDecode, @CheckForNull String expectedMessage) { try { encoding.decodeChecked(cannotDecode); fail("Expected DecodingException"); @@ -474,7 +474,7 @@ void assertFailsToDecode( }; abstract void assertFailsToDecode( - BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage); + BaseEncoding encoding, String cannotDecode, @CheckForNull String expectedMessage); } @GwtIncompatible // Reader/Writer diff --git a/android/guava-tests/test/com/google/common/io/ByteSourceTest.java b/android/guava-tests/test/com/google/common/io/ByteSourceTest.java index f0ba829b22eb..3cf6cca44259 100644 --- a/android/guava-tests/test/com/google/common/io/ByteSourceTest.java +++ b/android/guava-tests/test/com/google/common/io/ByteSourceTest.java @@ -30,6 +30,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.hash.Hashing; +import com.google.common.io.Closer.LoggingSuppressor; import com.google.common.primitives.UnsignedBytes; import com.google.common.testing.TestLogHandler; import java.io.ByteArrayOutputStream; @@ -395,7 +396,7 @@ public void testConcat_infiniteIterable() throws IOException { ImmutableSet.of(BROKEN_CLOSE_SINK, BROKEN_OPEN_SINK, BROKEN_WRITE_SINK); public void testCopyExceptions() { - if (!Closer.SuppressingSuppressor.isAvailable()) { + if (Closer.create().suppressor instanceof LoggingSuppressor) { // test that exceptions are logged TestLogHandler logHandler = new TestLogHandler(); diff --git a/android/guava-tests/test/com/google/common/io/ByteSourceTester.java b/android/guava-tests/test/com/google/common/io/ByteSourceTester.java index 490f1e6c5df7..75854125606a 100644 --- a/android/guava-tests/test/com/google/common/io/ByteSourceTester.java +++ b/android/guava-tests/test/com/google/common/io/ByteSourceTester.java @@ -38,7 +38,7 @@ /** * A generator of {@code TestSuite} instances for testing {@code ByteSource} implementations. * Generates tests of a all methods on a {@code ByteSource} given various inputs the source is - * expected to contain as well as as sub-suites for testing the {@code CharSource} view and {@code + * expected to contain as well as sub-suites for testing the {@code CharSource} view and {@code * slice()} views in the same way. * * @author Colin Decker diff --git a/android/guava-tests/test/com/google/common/io/ByteStreamsTest.java b/android/guava-tests/test/com/google/common/io/ByteStreamsTest.java index 3ae2c2559827..dddae1ffc21a 100644 --- a/android/guava-tests/test/com/google/common/io/ByteStreamsTest.java +++ b/android/guava-tests/test/com/google/common/io/ByteStreamsTest.java @@ -562,12 +562,49 @@ public void testNullOutputStream() throws Exception { // write to the output stream nos.write('n'); String test = "Test string for NullOutputStream"; - nos.write(test.getBytes()); - nos.write(test.getBytes(), 2, 10); + byte[] bytes = test.getBytes(Charsets.US_ASCII); + nos.write(bytes); + nos.write(bytes, 2, 10); + nos.write(bytes, bytes.length - 5, 5); // nothing really to assert? assertSame(ByteStreams.nullOutputStream(), ByteStreams.nullOutputStream()); } + public void testNullOutputStream_exceptions() throws Exception { + OutputStream nos = ByteStreams.nullOutputStream(); + try { + nos.write(null); + fail(); + } catch (NullPointerException expected) { + } + try { + nos.write(null, 0, 1); + fail(); + } catch (NullPointerException expected) { + } + byte[] tenBytes = new byte[10]; + try { + nos.write(tenBytes, -1, 1); + fail("Expected exception from negative offset"); + } catch (IndexOutOfBoundsException expected) { + } + try { + nos.write(tenBytes, 1, -1); + fail("Expected exception from negative length"); + } catch (IndexOutOfBoundsException expected) { + } + try { + nos.write(tenBytes, 9, 2); + fail("Expected exception from offset+length > array size"); + } catch (IndexOutOfBoundsException expected) { + } + try { + nos.write(tenBytes, 9, 100); + fail("Expected exception from offset+length > array size"); + } catch (IndexOutOfBoundsException expected) { + } + } + public void testLimit() throws Exception { byte[] big = newPreFilledByteArray(5); InputStream bin = new ByteArrayInputStream(big); diff --git a/android/guava-tests/test/com/google/common/io/CharSequenceReaderTest.java b/android/guava-tests/test/com/google/common/io/CharSequenceReaderTest.java index 12bc17e588e3..dbe94fcf71fa 100644 --- a/android/guava-tests/test/com/google/common/io/CharSequenceReaderTest.java +++ b/android/guava-tests/test/com/google/common/io/CharSequenceReaderTest.java @@ -211,7 +211,7 @@ private static void assertReadsCorrectly(CharSequence charSequence) throws IOExc reader = new CharSequenceReader(charSequence); CharBuffer buf2 = CharBuffer.allocate(expected.length()); assertEquals(expected.length() == 0 ? -1 : expected.length(), reader.read(buf2)); - buf2.flip(); + Java8Compatibility.flip(buf2); assertEquals(expected, buf2.toString()); assertFullyRead(reader); @@ -220,9 +220,9 @@ private static void assertReadsCorrectly(CharSequence charSequence) throws IOExc buf2 = CharBuffer.allocate(5); builder = new StringBuilder(); while (reader.read(buf2) != -1) { - buf2.flip(); + Java8Compatibility.flip(buf2); builder.append(buf2); - buf2.clear(); + Java8Compatibility.clear(buf2); } assertEquals(expected, builder.toString()); assertFullyRead(reader); diff --git a/android/guava-tests/test/com/google/common/io/CharSourceTest.java b/android/guava-tests/test/com/google/common/io/CharSourceTest.java index a1034904dd7c..6cc210b56c4e 100644 --- a/android/guava-tests/test/com/google/common/io/CharSourceTest.java +++ b/android/guava-tests/test/com/google/common/io/CharSourceTest.java @@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.io.Closer.LoggingSuppressor; import com.google.common.testing.TestLogHandler; import java.io.BufferedReader; import java.io.IOException; @@ -258,7 +259,7 @@ public void testConcat_infiniteIterable() throws IOException { ImmutableSet.of(BROKEN_CLOSE_SINK, BROKEN_OPEN_SINK, BROKEN_WRITE_SINK); public void testCopyExceptions() { - if (!Closer.SuppressingSuppressor.isAvailable()) { + if (Closer.create().suppressor instanceof LoggingSuppressor) { // test that exceptions are logged TestLogHandler logHandler = new TestLogHandler(); diff --git a/android/guava-tests/test/com/google/common/io/CloserTest.java b/android/guava-tests/test/com/google/common/io/CloserTest.java index b97a3057698a..38ff700c8c14 100644 --- a/android/guava-tests/test/com/google/common/io/CloserTest.java +++ b/android/guava-tests/test/com/google/common/io/CloserTest.java @@ -24,14 +24,15 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import com.google.common.io.Closer.LoggingSuppressor; import com.google.common.testing.TestLogHandler; import java.io.Closeable; import java.io.IOException; import java.lang.reflect.Method; import java.util.List; import java.util.logging.LogRecord; +import javax.annotation.CheckForNull; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Tests for {@link Closer}. @@ -311,13 +312,12 @@ record = logHandler.getStoredLogRecords().get(1); } public static void testSuppressingSuppressorIfPossible() throws IOException { + Closer closer = Closer.create(); // can't test the JDK7 suppressor when not running on JDK7 - if (!Closer.SuppressingSuppressor.isAvailable()) { + if (closer.suppressor instanceof LoggingSuppressor) { return; } - Closer closer = new Closer(new Closer.SuppressingSuppressor()); - IOException thrownException = new IOException(); IOException c1Exception = new IOException(); RuntimeException c2Exception = new RuntimeException(); @@ -435,7 +435,7 @@ static TestCloseable throwsOnCreate() throws IOException { throw new IOException(); } - private TestCloseable(@NullableDecl Throwable throwOnClose) { + private TestCloseable(@CheckForNull Throwable throwOnClose) { this.throwOnClose = throwOnClose; } diff --git a/android/guava-tests/test/com/google/common/io/LittleEndianDataInputStreamTest.java b/android/guava-tests/test/com/google/common/io/LittleEndianDataInputStreamTest.java index f8e40df25a98..160df410bed6 100644 --- a/android/guava-tests/test/com/google/common/io/LittleEndianDataInputStreamTest.java +++ b/android/guava-tests/test/com/google/common/io/LittleEndianDataInputStreamTest.java @@ -92,6 +92,7 @@ public void testReadUnsignedShort_eof() throws IOException { } } + @SuppressWarnings("DoNotCall") public void testReadLine() throws IOException { DataInput in = new LittleEndianDataInputStream(new ByteArrayInputStream(data)); try { diff --git a/android/guava-tests/test/com/google/common/io/PatternFilenameFilterTest.java b/android/guava-tests/test/com/google/common/io/PatternFilenameFilterTest.java index 77ace52f2506..94ab1f01683a 100644 --- a/android/guava-tests/test/com/google/common/io/PatternFilenameFilterTest.java +++ b/android/guava-tests/test/com/google/common/io/PatternFilenameFilterTest.java @@ -16,6 +16,8 @@ package com.google.common.io; +import com.google.common.testing.NullPointerTester; +import com.google.common.testing.NullPointerTester.Visibility; import java.io.File; import java.io.FilenameFilter; import java.util.regex.PatternSyntaxException; @@ -46,4 +48,15 @@ public void testAccept() { // Show that dir is ignored assertTrue(filter.accept(null, "a")); } + + public void testNulls() throws Exception { + NullPointerTester tester = new NullPointerTester(); + + tester.testConstructors(PatternFilenameFilter.class, Visibility.PACKAGE); + tester.testStaticMethods(PatternFilenameFilter.class, Visibility.PACKAGE); // currently none + + // The reason that we skip this method is discussed in a comment on the method. + tester.ignore(PatternFilenameFilter.class.getMethod("accept", File.class, String.class)); + tester.testInstanceMethods(new PatternFilenameFilter(".*"), Visibility.PACKAGE); + } } diff --git a/android/guava-tests/test/com/google/common/io/SourceSinkFactories.java b/android/guava-tests/test/com/google/common/io/SourceSinkFactories.java index 8bfa6e1ba12a..e70370e1d69b 100644 --- a/android/guava-tests/test/com/google/common/io/SourceSinkFactories.java +++ b/android/guava-tests/test/com/google/common/io/SourceSinkFactories.java @@ -37,7 +37,7 @@ import java.nio.CharBuffer; import java.util.Arrays; import java.util.logging.Logger; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * {@link SourceSinkFactory} implementations. @@ -305,7 +305,7 @@ private static class FileByteSinkFactory extends FileFactory implements ByteSink private final byte[] initialBytes; - private FileByteSinkFactory(@NullableDecl byte[] initialBytes) { + private FileByteSinkFactory(@CheckForNull byte[] initialBytes) { this.initialBytes = initialBytes; } @@ -375,7 +375,7 @@ private static class FileCharSinkFactory extends FileFactory implements CharSink private final String initialString; - private FileCharSinkFactory(@NullableDecl String initialString) { + private FileCharSinkFactory(@CheckForNull String initialString) { this.initialString = initialString; } @@ -407,9 +407,9 @@ public String getSinkContents() throws IOException { StringBuilder builder = new StringBuilder(); CharBuffer buffer = CharBuffer.allocate(100); while (reader.read(buffer) != -1) { - buffer.flip(); + Java8Compatibility.flip(buffer); builder.append(buffer); - buffer.clear(); + Java8Compatibility.clear(buffer); } return builder.toString(); } diff --git a/android/guava-tests/test/com/google/common/io/SourceSinkTester.java b/android/guava-tests/test/com/google/common/io/SourceSinkTester.java index 9b07355a6939..55a302f850c5 100644 --- a/android/guava-tests/test/com/google/common/io/SourceSinkTester.java +++ b/android/guava-tests/test/com/google/common/io/SourceSinkTester.java @@ -69,7 +69,7 @@ public class SourceSinkTester> extends T .put("\\n at EOF", "hello\nworld\n") .put("\\r at EOF", "hello\nworld\r") .put("lorem ipsum", LOREM_IPSUM) - .build(); + .buildOrThrow(); protected final F factory; protected final T data; diff --git a/android/guava-tests/test/com/google/common/math/IntMathTest.java b/android/guava-tests/test/com/google/common/math/IntMathTest.java index 12b23e214728..4db13adbddd5 100644 --- a/android/guava-tests/test/com/google/common/math/IntMathTest.java +++ b/android/guava-tests/test/com/google/common/math/IntMathTest.java @@ -137,10 +137,11 @@ public void testMaxLog10ForLeadingZeros() { @GwtIncompatible // BigIntegerMath // TODO(cpovirk): GWT-enable BigIntegerMath public void testConstantsHalfPowersOf10() { for (int i = 0; i < IntMath.halfPowersOf10.length; i++) { - assert IntMath.halfPowersOf10[i] - == Math.min( + assertEquals( + IntMath.halfPowersOf10[i], + Math.min( Integer.MAX_VALUE, - BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * i + 1), FLOOR).longValue()); + BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * i + 1), FLOOR).longValue())); } } diff --git a/android/guava-tests/test/com/google/common/math/MathPreconditionsTest.java b/android/guava-tests/test/com/google/common/math/MathPreconditionsTest.java index 69719e013572..5dbe017c142d 100644 --- a/android/guava-tests/test/com/google/common/math/MathPreconditionsTest.java +++ b/android/guava-tests/test/com/google/common/math/MathPreconditionsTest.java @@ -289,4 +289,15 @@ public void testCheckNoOverflow_failure() { assertThat(expected).hasMessageThat().contains("testCheckNoOverflow_failure(0, 0)"); } } + + public void testNulls() { + /* + * Don't bother testing. All non-primitive parameters are used only to construct error messages. + * We never want to pass null for them, so we haven't annotated them to say that null is + * allowed. But at the same time, it seems wasteful to bother inserting the checkNotNull calls + * that NullPointerTester wants. + * + * (This empty method disables the automatic null testing provided by PackageSanityTests.) + */ + } } diff --git a/android/guava-tests/test/com/google/common/math/QuantilesAlgorithm.java b/android/guava-tests/test/com/google/common/math/QuantilesAlgorithm.java index 54d310f0d2d6..ddb2064e20b6 100644 --- a/android/guava-tests/test/com/google/common/math/QuantilesAlgorithm.java +++ b/android/guava-tests/test/com/google/common/math/QuantilesAlgorithm.java @@ -53,7 +53,7 @@ Map multipleQuantiles( for (int index : indexes) { builder.put(index, singleQuantileFromSorted(index, scale, dataset)); } - return builder.build(); + return builder.buildOrThrow(); } private double singleQuantileFromSorted(int index, int scale, double[] dataset) { @@ -97,7 +97,7 @@ Map multipleQuantiles( for (int index : indexes) { builder.put(index, singleQuantile(index, scale, dataset)); } - return builder.build(); + return builder.buildOrThrow(); } }, diff --git a/android/guava-tests/test/com/google/common/math/QuantilesTest.java b/android/guava-tests/test/com/google/common/math/QuantilesTest.java index 5ac5f6e303e6..77c70207cdf9 100644 --- a/android/guava-tests/test/com/google/common/math/QuantilesTest.java +++ b/android/guava-tests/test/com/google/common/math/QuantilesTest.java @@ -41,8 +41,8 @@ import java.util.Collections; import java.util.List; import java.util.Random; +import javax.annotation.CheckForNull; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Tests for {@link Quantiles}. @@ -92,7 +92,7 @@ public class QuantilesTest extends TestCase { Correspondence.from( new BinaryPredicate() { @Override - public boolean apply(@NullableDecl Double actual, @NullableDecl Double expected) { + public boolean apply(@CheckForNull Double actual, @CheckForNull Double expected) { // Test for equality to allow non-finite values to match; otherwise, use the finite // test. return actual.equals(expected) @@ -557,7 +557,7 @@ public void testPercentiles_indexes_varargsPairs_compute_doubleCollection() { } assertThat(percentiles().indexes(index1, index2).compute(PSEUDORANDOM_DATASET)) .comparingValuesUsing(QUANTILE_CORRESPONDENCE) - .containsExactlyEntriesIn(expectedBuilder.build()); + .containsExactlyEntriesIn(expectedBuilder.buildOrThrow()); } } } @@ -573,7 +573,7 @@ public void testPercentiles_indexes_varargsAll_compute_doubleCollection() { Collections.shuffle(indexes, random); assertThat(percentiles().indexes(Ints.toArray(indexes)).compute(PSEUDORANDOM_DATASET)) .comparingValuesUsing(QUANTILE_CORRESPONDENCE) - .containsExactlyEntriesIn(expectedBuilder.build()); + .containsExactlyEntriesIn(expectedBuilder.buildOrThrow()); } @AndroidIncompatible // slow @@ -589,7 +589,7 @@ public void testPercentiles_indexes_varargsAll_computeInPlace() { Collections.shuffle(indexes, random); assertThat(percentiles().indexes(Ints.toArray(indexes)).computeInPlace(dataset)) .comparingValuesUsing(QUANTILE_CORRESPONDENCE) - .containsExactlyEntriesIn(expectedBuilder.build()); + .containsExactlyEntriesIn(expectedBuilder.buildOrThrow()); assertThat(dataset).usingExactEquality().containsExactlyElementsIn(PSEUDORANDOM_DATASET); } diff --git a/android/guava-tests/test/com/google/common/net/HostAndPortTest.java b/android/guava-tests/test/com/google/common/net/HostAndPortTest.java index 5e7eb2f73d71..65e80962bafa 100644 --- a/android/guava-tests/test/com/google/common/net/HostAndPortTest.java +++ b/android/guava-tests/test/com/google/common/net/HostAndPortTest.java @@ -59,6 +59,13 @@ public void testFromStringUnusedDefaultPort() { checkFromStringCase("[2001::2]:85", 77, "2001::2", 85, true); } + public void testFromStringNonAsciiDigits() { + // Same as testFromStringUnusedDefaultPort but with Gujarati digits for port numbers. + checkFromStringCase("gmail.com:૮1", 77, null, -1, false); + checkFromStringCase("192.0.2.2:૮૩", 77, null, -1, false); + checkFromStringCase("[2001::2]:૮૫", 77, null, -1, false); + } + public void testFromStringBadPort() { // Out-of-range ports. checkFromStringCase("google.com:65536", 1, null, 99, false); diff --git a/android/guava-tests/test/com/google/common/net/HostSpecifierTest.java b/android/guava-tests/test/com/google/common/net/HostSpecifierTest.java index fadeff7aadf4..8112879a86d9 100644 --- a/android/guava-tests/test/com/google/common/net/HostSpecifierTest.java +++ b/android/guava-tests/test/com/google/common/net/HostSpecifierTest.java @@ -92,8 +92,9 @@ public void testNulls() { } private void assertGood(String spec) throws ParseException { - HostSpecifier.fromValid(spec); // Throws exception if not working correctly - HostSpecifier.from(spec); + // Throws exception if not working correctly + HostSpecifier unused = HostSpecifier.fromValid(spec); + unused = HostSpecifier.from(spec); assertTrue(HostSpecifier.isValid(spec)); } diff --git a/android/guava-tests/test/com/google/common/net/HttpHeadersTest.java b/android/guava-tests/test/com/google/common/net/HttpHeadersTest.java index 9927e6b94e00..5361b3fcea61 100644 --- a/android/guava-tests/test/com/google/common/net/HttpHeadersTest.java +++ b/android/guava-tests/test/com/google/common/net/HttpHeadersTest.java @@ -50,8 +50,8 @@ public void testConstantNameMatchesString() throws Exception { .build(); ImmutableSet uppercaseAcronyms = ImmutableSet.of( - "CH", "ID", "DNT", "DNS", "HTTP2", "IP", "MD5", "P3P", "TE", "UA", "UID", "URL", "WWW", - "XSS"); + "CH", "ID", "DNT", "DNS", "ECT", "HTTP2", "IP", "MD5", "P3P", "RTT", "TE", "UA", "UID", + "URL", "WWW", "XSS"); assertConstantNameMatchesString(HttpHeaders.class, specialCases, uppercaseAcronyms); } diff --git a/android/guava-tests/test/com/google/common/net/InetAddressesTest.java b/android/guava-tests/test/com/google/common/net/InetAddressesTest.java index ed3aa272d3a6..be77e7b17f08 100644 --- a/android/guava-tests/test/com/google/common/net/InetAddressesTest.java +++ b/android/guava-tests/test/com/google/common/net/InetAddressesTest.java @@ -135,6 +135,20 @@ public void testForStringIPv4Input() throws UnknownHostException { assertTrue(InetAddresses.isInetAddress(ipStr)); } + public void testForStringIPv4NonAsciiInput() throws UnknownHostException { + String ipStr = "૧૯૨.૧૬૮.૦.૧"; // 192.168.0.1 in Gujarati digits + // Shouldn't hit DNS, because it's an IP string literal. + InetAddress ipv4Addr; + try { + ipv4Addr = InetAddress.getByName(ipStr); + } catch (UnknownHostException e) { + // OK: this is probably Android, which is stricter. + return; + } + assertEquals(ipv4Addr, InetAddresses.forString(ipStr)); + assertTrue(InetAddresses.isInetAddress(ipStr)); + } + public void testForStringIPv6Input() throws UnknownHostException { String ipStr = "3ffe::1"; // Shouldn't hit DNS, because it's an IP string literal. @@ -143,6 +157,20 @@ public void testForStringIPv6Input() throws UnknownHostException { assertTrue(InetAddresses.isInetAddress(ipStr)); } + public void testForStringIPv6NonAsciiInput() throws UnknownHostException { + String ipStr = "૩ffe::૧"; // 3ffe::1 with Gujarati digits for 3 and 1 + // Shouldn't hit DNS, because it's an IP string literal. + InetAddress ipv6Addr; + try { + ipv6Addr = InetAddress.getByName(ipStr); + } catch (UnknownHostException e) { + // OK: this is probably Android, which is stricter. + return; + } + assertEquals(ipv6Addr, InetAddresses.forString(ipStr)); + assertTrue(InetAddresses.isInetAddress(ipStr)); + } + public void testForStringIPv6EightColons() throws UnknownHostException { ImmutableSet eightColons = ImmutableSet.of("::7:6:5:4:3:2:1", "::7:6:5:4:3:2:0", "7:6:5:4:3:2:1::", "0:6:5:4:3:2:1::"); diff --git a/android/guava-tests/test/com/google/common/net/InternetDomainNameTest.java b/android/guava-tests/test/com/google/common/net/InternetDomainNameTest.java index 7113fb45741a..c440ee53f509 100644 --- a/android/guava-tests/test/com/google/common/net/InternetDomainNameTest.java +++ b/android/guava-tests/test/com/google/common/net/InternetDomainNameTest.java @@ -232,7 +232,7 @@ public final class InternetDomainNameTest extends TestCase { public void testValid() { for (String name : VALID_NAME) { - InternetDomainName.from(name); + InternetDomainName unused = InternetDomainName.from(name); } } @@ -392,7 +392,7 @@ public void testParentChild() { // These would throw an exception if leniency were not preserved during parent() and child() // calls. InternetDomainName child = parent.child(LOTS_OF_DELTAS); - child.child(LOTS_OF_DELTAS); + InternetDomainName unused = child.child(LOTS_OF_DELTAS); } public void testValidTopPrivateDomain() { diff --git a/android/guava-tests/test/com/google/common/net/MediaTypeTest.java b/android/guava-tests/test/com/google/common/net/MediaTypeTest.java index cec3cdd28cce..574db68e80b3 100644 --- a/android/guava-tests/test/com/google/common/net/MediaTypeTest.java +++ b/android/guava-tests/test/com/google/common/net/MediaTypeTest.java @@ -46,7 +46,6 @@ import com.google.common.testing.NullPointerTester; import java.lang.reflect.Field; import java.nio.charset.Charset; -import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; import java.util.Arrays; import junit.framework.TestCase; @@ -537,7 +536,7 @@ public void testGetCharset_illegalCharset() { try { mediaType.charset(); fail(); - } catch (IllegalCharsetNameException expected) { + } catch (IllegalArgumentException expected) { } } diff --git a/android/guava-tests/test/com/google/common/net/PercentEscaperTest.java b/android/guava-tests/test/com/google/common/net/PercentEscaperTest.java index 8443680e7f11..e600e4c7c1af 100644 --- a/android/guava-tests/test/com/google/common/net/PercentEscaperTest.java +++ b/android/guava-tests/test/com/google/common/net/PercentEscaperTest.java @@ -120,16 +120,11 @@ public void testBadArguments_badchars() { } } - /** - * Tests that if space is a safe character you cannot also specify 'plusForSpace' (throws {@link - * IllegalArgumentException}). - */ public void testBadArguments_plusforspace() { - try { - new PercentEscaper(" ", false); - } catch (IllegalArgumentException e) { - fail("Space can be a 'safe' character if plusForSpace is false"); - } + // space can be a safe char if plusForSpace is false + PercentEscaper unused = new PercentEscaper(" ", false); + + // space cannot be a safe char is plusForSpace is true String msg = "plusForSpace cannot be specified when space is a 'safe' character"; try { new PercentEscaper(" ", true); diff --git a/android/guava-tests/test/com/google/common/primitives/BooleansTest.java b/android/guava-tests/test/com/google/common/primitives/BooleansTest.java index 560c33700382..43ec04c4a4a4 100644 --- a/android/guava-tests/test/com/google/common/primitives/BooleansTest.java +++ b/android/guava-tests/test/com/google/common/primitives/BooleansTest.java @@ -299,7 +299,8 @@ public void testAsListEquals() { assertEquals(1, Booleans.asList(ARRAY_FALSE_TRUE).lastIndexOf(true)); List reference = Booleans.asList(ARRAY_FALSE); assertEquals(Booleans.asList(ARRAY_FALSE), reference); - assertEquals(reference, reference); + // Explicitly call `equals`; `assertEquals` might return fast + assertTrue(reference.equals(reference)); } public void testAsListHashcode() { diff --git a/android/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java b/android/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java index dd2a8ab88bfc..cfa2862573aa 100644 --- a/android/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java +++ b/android/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java @@ -36,13 +36,23 @@ public class UnsignedLongTest extends TestCase { static { ImmutableSet.Builder testLongsBuilder = ImmutableSet.builder(); ImmutableSet.Builder testBigIntegersBuilder = ImmutableSet.builder(); + + // The values here look like 111...11101...010 in binary, where the initial 111...1110 takes + // up exactly as many bits as can be represented in the significand (24 for float, 53 for + // double). That final 0 should be rounded up to 1 because the remaining bits make that number + // slightly nearer. + long floatConversionTest = 0xfffffe8000000002L; + long doubleConversionTest = 0xfffffffffffff402L; + for (long i = -3; i <= 3; i++) { testLongsBuilder .add(i) .add(Long.MAX_VALUE + i) .add(Long.MIN_VALUE + i) .add(Integer.MIN_VALUE + i) - .add(Integer.MAX_VALUE + i); + .add(Integer.MAX_VALUE + i) + .add(floatConversionTest + i) + .add(doubleConversionTest + i); BigInteger bigI = BigInteger.valueOf(i); testBigIntegersBuilder .add(bigI) @@ -130,17 +140,26 @@ public void testToStringRadixQuick() { } } + @AndroidIncompatible // b/28251030, re-enable when the fix is everywhere we run this test public void testFloatValue() { for (long value : TEST_LONGS) { UnsignedLong unsignedValue = UnsignedLong.fromLongBits(value); - assertEquals(unsignedValue.bigIntegerValue().floatValue(), unsignedValue.floatValue()); + assertEquals( + "Float value of " + unsignedValue, + unsignedValue.bigIntegerValue().floatValue(), + unsignedValue.floatValue(), + 0.0f); } } public void testDoubleValue() { for (long value : TEST_LONGS) { UnsignedLong unsignedValue = UnsignedLong.fromLongBits(value); - assertEquals(unsignedValue.bigIntegerValue().doubleValue(), unsignedValue.doubleValue()); + assertEquals( + "Double value of " + unsignedValue, + unsignedValue.bigIntegerValue().doubleValue(), + unsignedValue.doubleValue(), + 0.0); } } diff --git a/android/guava-tests/test/com/google/common/reflect/ElementTest.java b/android/guava-tests/test/com/google/common/reflect/ElementTest.java deleted file mode 100644 index abe63ba56163..000000000000 --- a/android/guava-tests/test/com/google/common/reflect/ElementTest.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.reflect; - -import com.google.common.testing.EqualsTester; -import com.google.common.testing.NullPointerTester; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.reflect.Constructor; -import junit.framework.TestCase; - -/** - * Unit tests of {@link Element}. - * - * @author Ben Yu - */ -public class ElementTest extends TestCase { - - public void testPrivateField() throws Exception { - Element element = A.field("privateField"); - assertTrue(element.isPrivate()); - assertFalse(element.isAbstract()); - assertFalse(element.isPackagePrivate()); - assertFalse(element.isProtected()); - assertFalse(element.isPublic()); - assertFalse(element.isFinal()); - assertFalse(element.isStatic()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testPackagePrivateField() throws Exception { - Element element = A.field("packagePrivateField"); - assertFalse(element.isPrivate()); - assertTrue(element.isPackagePrivate()); - assertFalse(element.isProtected()); - assertFalse(element.isPublic()); - assertFalse(element.isFinal()); - assertFalse(element.isStatic()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testProtectedField() throws Exception { - Element element = A.field("protectedField"); - assertFalse(element.isPrivate()); - assertFalse(element.isPackagePrivate()); - assertTrue(element.isProtected()); - assertFalse(element.isPublic()); - assertFalse(element.isFinal()); - assertFalse(element.isStatic()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testPublicField() throws Exception { - Element element = A.field("publicField"); - assertFalse(element.isPrivate()); - assertFalse(element.isPackagePrivate()); - assertFalse(element.isProtected()); - assertTrue(element.isPublic()); - assertFalse(element.isFinal()); - assertFalse(element.isStatic()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testFinalField() throws Exception { - Element element = A.field("finalField"); - assertTrue(element.isFinal()); - assertFalse(element.isStatic()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testStaticField() throws Exception { - Element element = A.field("staticField"); - assertTrue(element.isStatic()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testVolatileField() throws Exception { - Element element = A.field("volatileField"); - assertTrue(element.isVolatile()); - } - - public void testTransientField() throws Exception { - Element element = A.field("transientField"); - assertTrue(element.isTransient()); - } - - public void testConstructor() throws Exception { - Element element = A.constructor(); - assertTrue(element.isPublic()); - assertFalse(element.isPackagePrivate()); - assertFalse(element.isAbstract()); - assertFalse(element.isStatic()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testAbstractMethod() throws Exception { - Element element = A.method("abstractMethod"); - assertTrue(element.isPackagePrivate()); - assertTrue(element.isAbstract()); - assertFalse(element.isFinal()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testOverridableMethod() throws Exception { - Element element = A.method("overridableMethod"); - assertTrue(element.isPackagePrivate()); - assertFalse(element.isAbstract()); - assertFalse(element.isFinal()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testPrivateMethod() throws Exception { - Element element = A.method("privateMethod"); - assertFalse(element.isAbstract()); - assertTrue(element.isPrivate()); - assertFalse(element.isPackagePrivate()); - assertFalse(element.isPublic()); - assertFalse(element.isProtected()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testProtectedMethod() throws Exception { - Element element = A.method("protectedMethod"); - assertFalse(element.isAbstract()); - assertFalse(element.isPrivate()); - assertFalse(element.isPackagePrivate()); - assertFalse(element.isFinal()); - assertFalse(element.isPublic()); - assertTrue(element.isProtected()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testFinalMethod() throws Exception { - Element element = A.method("publicFinalMethod"); - assertFalse(element.isAbstract()); - assertFalse(element.isPrivate()); - assertTrue(element.isFinal()); - assertTrue(element.isPublic()); - assertTrue(element.isAnnotationPresent(Tested.class)); - } - - public void testNativeMethod() throws Exception { - Element element = A.method("nativeMethod"); - assertTrue(element.isNative()); - assertTrue(element.isPackagePrivate()); - } - - public void testSynchronizedMethod() throws Exception { - Element element = A.method("synchronizedMethod"); - assertTrue(element.isSynchronized()); - } - - public void testUnannotatedMethod() throws Exception { - Element element = A.method("notAnnotatedMethod"); - assertFalse(element.isAnnotationPresent(Tested.class)); - } - - public void testEquals() throws Exception { - new EqualsTester() - .addEqualityGroup(A.field("privateField"), A.field("privateField")) - .addEqualityGroup(A.field("publicField")) - .addEqualityGroup(A.constructor(), A.constructor()) - .addEqualityGroup(A.method("privateMethod"), A.method("privateMethod")) - .addEqualityGroup(A.method("publicFinalMethod")) - .testEquals(); - } - - public void testNulls() { - new NullPointerTester().testAllPublicStaticMethods(Element.class); - } - - @Retention(RetentionPolicy.RUNTIME) - private @interface Tested {} - - private abstract static class A { - @Tested private boolean privateField; - @Tested int packagePrivateField; - @Tested protected int protectedField; - @Tested public String publicField; - @Tested private static Iterable staticField; - @Tested private final Object finalField; - private volatile char volatileField; - private transient long transientField; - - @Tested - public A(Object finalField) { - this.finalField = finalField; - } - - @Tested - abstract void abstractMethod(); - - @Tested - void overridableMethod() {} - - @Tested - protected void protectedMethod() {} - - @Tested - private void privateMethod() {} - - @Tested - public final void publicFinalMethod() {} - - void notAnnotatedMethod() {} - - static Element field(String name) throws Exception { - Element element = new Element(A.class.getDeclaredField(name)); - assertEquals(name, element.getName()); - assertEquals(A.class, element.getDeclaringClass()); - return element; - } - - static Element constructor() throws Exception { - Constructor constructor = A.class.getDeclaredConstructor(Object.class); - Element element = new Element(constructor); - assertEquals(constructor.getName(), element.getName()); - assertEquals(A.class, element.getDeclaringClass()); - return element; - } - - static Element method(String name, Class... parameterTypes) throws Exception { - Element element = new Element(A.class.getDeclaredMethod(name, parameterTypes)); - assertEquals(name, element.getName()); - assertEquals(A.class, element.getDeclaringClass()); - return element; - } - - native void nativeMethod(); - - synchronized void synchronizedMethod() {} - } -} diff --git a/android/guava-tests/test/com/google/common/reflect/InvokableTest.java b/android/guava-tests/test/com/google/common/reflect/InvokableTest.java index 816aed3326ee..e545bdd1b903 100644 --- a/android/guava-tests/test/com/google/common/reflect/InvokableTest.java +++ b/android/guava-tests/test/com/google/common/reflect/InvokableTest.java @@ -19,18 +19,21 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.TypeVariable; import java.util.Collections; +import javax.annotation.CheckForNull; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Unit tests for {@link Invokable}. @@ -39,6 +42,180 @@ */ @AndroidIncompatible // lots of failures, possibly some related to bad equals() implementations? public class InvokableTest extends TestCase { + // Historically Invokable inherited from java.lang.reflect.AccessibleObject. That's no longer the + // case, but we do check that its API still has the same public methods. We exclude some methods + // that were added in Java 9 and that people probably weren't calling via Invokable, namely + // `boolean canAccess(Object)`. + public void testApiCompatibleWithAccessibleObject() { + ImmutableSet invokableMethods = + publicMethodSignatures(Invokable.class, ImmutableSet.of()); + ImmutableSet accesibleObjectMethods = + publicMethodSignatures(AccessibleObject.class, ImmutableSet.of("canAccess")); + assertThat(invokableMethods).containsAtLeastElementsIn(accesibleObjectMethods); + Class genericDeclaration; + try { + genericDeclaration = Class.forName("java.lang.reflect.GenericDeclaration"); + ImmutableSet genericDeclarationMethods = + publicMethodSignatures(genericDeclaration, ImmutableSet.of()); + assertThat(invokableMethods).containsAtLeastElementsIn(genericDeclarationMethods); + } catch (ClassNotFoundException e) { + // OK: we're on Java 7, which doesn't have this class + } + } + + private static ImmutableSet publicMethodSignatures( + Class c, ImmutableSet ignore) { + ImmutableSet.Builder methods = ImmutableSet.builder(); + for (Method method : c.getMethods()) { + if (Modifier.isStatic(method.getModifiers()) || ignore.contains(method.getName())) { + continue; + } + StringBuilder signature = + new StringBuilder() + .append(typeName(method.getReturnType())) + .append(" ") + .append(method.getName()) + .append("("); + String sep = ""; + for (Class param : method.getParameterTypes()) { + signature.append(sep).append(typeName(param)); + sep = ", "; + } + methods.add(signature.append(")").toString()); + } + return methods.build(); + } + + private static String typeName(Class type) { + return type.isArray() ? typeName(type.getComponentType()) + "[]" : type.getName(); + } + + public void testConstructor() throws Exception { + Invokable invokable = A.constructor(); + assertTrue(invokable.isPublic()); + assertFalse(invokable.isPackagePrivate()); + assertFalse(invokable.isAbstract()); + assertFalse(invokable.isStatic()); + assertTrue(invokable.isAnnotationPresent(Tested.class)); + } + + public void testAbstractMethod() throws Exception { + Invokable invokable = A.method("abstractMethod"); + assertTrue(invokable.isPackagePrivate()); + assertTrue(invokable.isAbstract()); + assertFalse(invokable.isFinal()); + assertTrue(invokable.isAnnotationPresent(Tested.class)); + } + + public void testOverridableMethod() throws Exception { + Invokable invokable = A.method("overridableMethod"); + assertTrue(invokable.isPackagePrivate()); + assertFalse(invokable.isAbstract()); + assertFalse(invokable.isFinal()); + assertTrue(invokable.isAnnotationPresent(Tested.class)); + } + + public void testPrivateMethod() throws Exception { + Invokable invokable = A.method("privateMethod"); + assertFalse(invokable.isAbstract()); + assertTrue(invokable.isPrivate()); + assertFalse(invokable.isPackagePrivate()); + assertFalse(invokable.isPublic()); + assertFalse(invokable.isProtected()); + assertTrue(invokable.isAnnotationPresent(Tested.class)); + } + + public void testProtectedMethod() throws Exception { + Invokable invokable = A.method("protectedMethod"); + assertFalse(invokable.isAbstract()); + assertFalse(invokable.isPrivate()); + assertFalse(invokable.isPackagePrivate()); + assertFalse(invokable.isFinal()); + assertFalse(invokable.isPublic()); + assertTrue(invokable.isProtected()); + assertTrue(invokable.isAnnotationPresent(Tested.class)); + } + + public void testFinalMethod() throws Exception { + Invokable invokable = A.method("publicFinalMethod"); + assertFalse(invokable.isAbstract()); + assertFalse(invokable.isPrivate()); + assertTrue(invokable.isFinal()); + assertTrue(invokable.isPublic()); + assertTrue(invokable.isAnnotationPresent(Tested.class)); + } + + public void testNativeMethod() throws Exception { + Invokable invokable = A.method("nativeMethod"); + assertTrue(invokable.isNative()); + assertTrue(invokable.isPackagePrivate()); + } + + public void testSynchronizedMethod() throws Exception { + Invokable invokable = A.method("synchronizedMethod"); + assertTrue(invokable.isSynchronized()); + } + + public void testUnannotatedMethod() throws Exception { + Invokable invokable = A.method("notAnnotatedMethod"); + assertFalse(invokable.isAnnotationPresent(Tested.class)); + } + + @Retention(RetentionPolicy.RUNTIME) + private @interface Tested {} + + private abstract static class A { + @Tested private boolean privateField; + @Tested int packagePrivateField; + @Tested protected int protectedField; + @Tested public String publicField; + @Tested private static Iterable staticField; + @Tested private final Object finalField; + private volatile char volatileField; + private transient long transientField; + + @Tested + public A(Object finalField) { + this.finalField = finalField; + } + + @Tested + abstract void abstractMethod(); + + @Tested + void overridableMethod() {} + + @Tested + protected void protectedMethod() {} + + @Tested + private void privateMethod() {} + + @Tested + public final void publicFinalMethod() {} + + void notAnnotatedMethod() {} + + static Invokable constructor() throws Exception { + Constructor constructor = A.class.getDeclaredConstructor(Object.class); + Invokable invokable = Invokable.from(constructor); + assertEquals(constructor.getName(), invokable.getName()); + assertEquals(A.class, invokable.getDeclaringClass()); + return invokable; + } + + static Invokable method(String name, Class... parameterTypes) throws Exception { + Invokable invokable = + Invokable.from(A.class.getDeclaredMethod(name, parameterTypes)); + assertEquals(name, invokable.getName()); + assertEquals(A.class, invokable.getDeclaringClass()); + return invokable; + } + + native void nativeMethod(); + + synchronized void synchronizedMethod() {} + } public void testConstructor_returnType() throws Exception { assertEquals(Prepender.class, Prepender.constructor().getReturnType().getType()); @@ -74,7 +251,7 @@ public void testConstructor_exceptionTypes() throws Exception { public void testConstructor_typeParameters() throws Exception { TypeVariable[] variables = Prepender.constructor().getTypeParameters(); assertThat(variables).hasLength(1); - assertEquals("A", variables[0].getName()); + assertEquals("T", variables[0].getName()); } public void testConstructor_parameters() throws Exception { @@ -343,7 +520,7 @@ public void testInnerClassWithOneParameterConstructor() { private class InnerWithAnnotatedConstructorParameter { @SuppressWarnings("unused") // called by reflection - InnerWithAnnotatedConstructorParameter(@NullableDecl String s) {} + InnerWithAnnotatedConstructorParameter(@CheckForNull String s) {} } public void testInnerClassWithAnnotatedConstructorParameter() { @@ -424,7 +601,7 @@ public void run() { } public void testAnonymousClassInConstructor() { - new AnonymousClassInConstructor(); + AnonymousClassInConstructor unused = new AnonymousClassInConstructor(); } private static class AnonymousClassInConstructor { @@ -444,7 +621,7 @@ public void run() { } public void testLocalClassInInstanceInitializer() { - new LocalClassInInstanceInitializer(); + LocalClassInInstanceInitializer unused = new LocalClassInInstanceInitializer(); } private static class LocalClassInInstanceInitializer { @@ -456,7 +633,7 @@ class Local {} } public void testLocalClassInStaticInitializer() { - new LocalClassInStaticInitializer(); + LocalClassInStaticInitializer unused = new LocalClassInStaticInitializer(); } private static class LocalClassInStaticInitializer { @@ -468,7 +645,8 @@ class Local {} } public void testLocalClassWithSeeminglyHiddenThisInStaticInitializer_BUG() { - new LocalClassWithSeeminglyHiddenThisInStaticInitializer(); + LocalClassWithSeeminglyHiddenThisInStaticInitializer unused = + new LocalClassWithSeeminglyHiddenThisInStaticInitializer(); } /** @@ -506,7 +684,7 @@ public LocalWithOneParameterConstructor(String x) { public void testLocalClassWithAnnotatedConstructorParameter() throws Exception { class LocalWithAnnotatedConstructorParameter { @SuppressWarnings("unused") // called by reflection - LocalWithAnnotatedConstructorParameter(@NullableDecl String s) {} + LocalWithAnnotatedConstructorParameter(@CheckForNull String s) {} } Constructor constructor = LocalWithAnnotatedConstructorParameter.class.getDeclaredConstructors()[0]; @@ -530,6 +708,9 @@ class LocalWithGenericConstructorParameter { public void testEquals() throws Exception { new EqualsTester() + .addEqualityGroup(A.constructor(), A.constructor()) + .addEqualityGroup(A.method("privateMethod"), A.method("privateMethod")) + .addEqualityGroup(A.method("publicFinalMethod")) .addEqualityGroup(Prepender.constructor(), Prepender.constructor()) .addEqualityGroup(Prepender.constructor(String.class, int.class)) .addEqualityGroup(Prepender.method("privateMethod"), Prepender.method("privateMethod")) @@ -562,7 +743,7 @@ private static class Prepender { } // just for testing - private Prepender() { + private Prepender() { this(null, 0); } diff --git a/android/guava-tests/test/com/google/common/reflect/TypeTokenTest.java b/android/guava-tests/test/com/google/common/reflect/TypeTokenTest.java index 171ef49fdb80..79732090a132 100644 --- a/android/guava-tests/test/com/google/common/reflect/TypeTokenTest.java +++ b/android/guava-tests/test/com/google/common/reflect/TypeTokenTest.java @@ -402,7 +402,7 @@ public void testGetGenericSuperclass_typeVariable_unbounded() { assertEquals(TypeToken.of(Object.class), new TypeToken() {}.getGenericSuperclass()); } - public & CharSequence> + public & Serializable> void testGetGenericSuperclass_typeVariable_boundIsClass() { assertEquals( new TypeToken>() {}, @@ -410,7 +410,7 @@ void testGetGenericSuperclass_typeVariable_boundIsClass() { assertEquals(TypeToken.of(Object.class), new TypeToken() {}.getGenericSuperclass()); } - public & CharSequence> + public & Serializable> void testGetGenericSuperclass_typeVariable_boundIsFBoundedClass() { assertEquals( new TypeToken>() {}, @@ -418,13 +418,13 @@ void testGetGenericSuperclass_typeVariable_boundIsFBoundedClass() { assertEquals(TypeToken.of(Object.class), new TypeToken() {}.getGenericSuperclass()); } - public & CharSequence> + public & Serializable> void testGetGenericSuperclass_typeVariable_boundIsInterface() { assertNull(TypeToken.of(new TypeCapture() {}.capture()).getGenericSuperclass()); assertEquals(TypeToken.of(Object.class), new TypeToken() {}.getGenericSuperclass()); } - public & CharSequence, T1 extends T> + public & Serializable, T1 extends T> void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndClass() { assertEquals( TypeToken.of(new TypeCapture() {}.capture()), @@ -432,7 +432,7 @@ void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndClass() { assertEquals(TypeToken.of(Object.class), new TypeToken() {}.getGenericSuperclass()); } - public & CharSequence, T1 extends T> + public & Serializable, T1 extends T> void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndInterface() { assertNull(TypeToken.of(new TypeCapture() {}.capture()).getGenericSuperclass()); assertEquals(TypeToken.of(Object.class), new TypeToken() {}.getGenericSuperclass()); @@ -1101,7 +1101,7 @@ public void testGetSupertype_withoutTypeVariable() { } public void testGetSupertype_chained() { - @SuppressWarnings("unchecked") // StringListIterable extensd ListIterable + @SuppressWarnings("unchecked") // StringListIterable extends ListIterable TypeToken> listIterableType = (TypeToken>) TypeToken.of(StringListIterable.class).getSupertype(ListIterable.class); @@ -1793,7 +1793,7 @@ private abstract static class RawTypeConsistencyTester & CharS abstract > void acceptT2(T2 t2); - static void verifyConsitentRawType() { + static void verifyConsistentRawType() { for (Method method : RawTypeConsistencyTester.class.getDeclaredMethods()) { assertEquals( method.getReturnType(), TypeToken.of(method.getGenericReturnType()).getRawType()); @@ -1807,7 +1807,7 @@ static void verifyConsitentRawType() { } public void testRawTypes() { - RawTypeConsistencyTester.verifyConsitentRawType(); + RawTypeConsistencyTester.verifyConsistentRawType(); assertEquals(Object.class, TypeToken.of(Types.subtypeOf(Object.class)).getRawType()); assertEquals( CharSequence.class, TypeToken.of(Types.subtypeOf(CharSequence.class)).getRawType()); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractAbstractFutureTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractAbstractFutureTest.java index f49b96245db4..991cada29a11 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractAbstractFutureTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractAbstractFutureTest.java @@ -359,7 +359,6 @@ public void testNegativeTimeout() throws Exception { } @GwtIncompatible // threads - public void testOverflowTimeout() throws Exception { // First, sanity check that naive multiplication would really overflow to a negative number: long nanosPerSecond = NANOSECONDS.convert(1, SECONDS); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java similarity index 91% rename from android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureTest.java rename to android/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java index f5f12db824ca..8f0fde236602 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java @@ -81,7 +81,7 @@ * ClosingFuture#finishToValueAndCloser(ValueAndCloserConsumer, Executor)} paths to complete a * {@link ClosingFuture} pipeline. */ -public abstract class ClosingFutureTest extends TestCase { +public abstract class AbstractClosingFutureTest extends TestCase { // TODO(dpb): Use Expect once that supports JUnit 3, or we can use JUnit 4. final List failures = new ArrayList<>(); final StandardSubjectBuilder expect = @@ -1616,7 +1616,7 @@ public Closeable call(DeferredCloser closer) throws Exception { /** * Marks the given step final and waits for it to fail. Expects the failure exception to match - * {@link ClosingFutureTest#exception}. + * {@link AbstractClosingFutureTest#exception}. */ abstract void assertFinallyFailsWithException(ClosingFuture closingFuture); @@ -1628,191 +1628,6 @@ void waitUntilClosed(ClosingFuture closingFuture) { assertTrue(awaitUninterruptibly(closingFuture.whenClosedCountDown(), 1, SECONDS)); } - /** Tests for {@link ClosingFuture} that exercise {@link ClosingFuture#finishToFuture()}. */ - - public static class FinishToFutureTest extends ClosingFutureTest { - - public void testFinishToFuture_throwsIfCalledTwice() throws Exception { - ClosingFuture closingFuture = - ClosingFuture.submit( - new ClosingCallable() { - @Override - public Closeable call(DeferredCloser closer) throws Exception { - return closer.eventuallyClose(mockCloseable, executor); - } - }, - executor); - FluentFuture unused = closingFuture.finishToFuture(); - try { - FluentFuture unused2 = closingFuture.finishToFuture(); - fail("should have thrown"); - } catch (IllegalStateException expected) { - } - } - - public void testFinishToFuture_throwsAfterCallingFinishToValueAndCloser() throws Exception { - ClosingFuture closingFuture = - ClosingFuture.submit( - new ClosingCallable() { - @Override - public Closeable call(DeferredCloser closer) throws Exception { - return closer.eventuallyClose(mockCloseable, executor); - } - }, - executor); - closingFuture.finishToValueAndCloser(new NoOpValueAndCloserConsumer<>(), directExecutor()); - try { - FluentFuture unused = closingFuture.finishToFuture(); - fail("should have thrown"); - } catch (IllegalStateException expected) { - } - } - - public void testFinishToFuture_preventsFurtherDerivation() { - ClosingFuture closingFuture = ClosingFuture.from(immediateFuture("value1")); - FluentFuture unused = closingFuture.finishToFuture(); - assertDerivingThrowsIllegalStateException(closingFuture); - } - - @Override - T getFinalValue(ClosingFuture closingFuture) throws ExecutionException { - return getUninterruptibly(closingFuture.finishToFuture()); - } - - @Override - void assertFinallyFailsWithException(ClosingFuture closingFuture) { - assertThatFutureFailsWithException(closingFuture.finishToFuture()); - } - - @Override - void assertBecomesCanceled(ClosingFuture closingFuture) throws ExecutionException { - assertThatFutureBecomesCancelled(closingFuture.finishToFuture()); - } - - @Override - void cancelFinalStepAndWait(ClosingFuture closingFuture) { - assertThat(closingFuture.finishToFuture().cancel(false)).isTrue(); - waitUntilClosed(closingFuture); - futureCancelled.countDown(); - } - } - - /** - * Tests for {@link ClosingFuture} that exercise {@link - * ClosingFuture#finishToValueAndCloser(ValueAndCloserConsumer, Executor)}. - */ - - public static class FinishToValueAndCloserTest extends ClosingFutureTest { - - private final ExecutorService finishToValueAndCloserExecutor = newSingleThreadExecutor(); - private volatile ValueAndCloser valueAndCloser; - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - assertWithMessage("finishToValueAndCloserExecutor was shut down") - .that(shutdownAndAwaitTermination(finishToValueAndCloserExecutor, 10, SECONDS)) - .isTrue(); - } - - public void testFinishToValueAndCloser_throwsIfCalledTwice() throws Exception { - ClosingFuture closingFuture = - ClosingFuture.submit( - new ClosingCallable() { - @Override - public Closeable call(DeferredCloser closer) throws Exception { - return closer.eventuallyClose(mockCloseable, executor); - } - }, - executor); - closingFuture.finishToValueAndCloser( - new NoOpValueAndCloserConsumer<>(), finishToValueAndCloserExecutor); - try { - closingFuture.finishToValueAndCloser( - new NoOpValueAndCloserConsumer<>(), finishToValueAndCloserExecutor); - fail("should have thrown"); - } catch (IllegalStateException expected) { - } - } - - public void testFinishToValueAndCloser_throwsAfterCallingFinishToFuture() throws Exception { - ClosingFuture closingFuture = - ClosingFuture.submit( - new ClosingCallable() { - @Override - public Closeable call(DeferredCloser closer) throws Exception { - return closer.eventuallyClose(mockCloseable, executor); - } - }, - executor); - FluentFuture unused = closingFuture.finishToFuture(); - try { - closingFuture.finishToValueAndCloser( - new NoOpValueAndCloserConsumer<>(), finishToValueAndCloserExecutor); - fail("should have thrown"); - } catch (IllegalStateException expected) { - } - } - - @Override - T getFinalValue(ClosingFuture closingFuture) throws ExecutionException { - return finishToValueAndCloser(closingFuture).get(); - } - - @Override - void assertFinallyFailsWithException(ClosingFuture closingFuture) { - assertThatFutureFailsWithException(closingFuture.statusFuture()); - ValueAndCloser valueAndCloser = finishToValueAndCloser(closingFuture); - try { - valueAndCloser.get(); - fail(); - } catch (ExecutionException expected) { - assertThat(expected).hasCauseThat().isSameInstanceAs(exception); - } - valueAndCloser.closeAsync(); - } - - @Override - void assertBecomesCanceled(ClosingFuture closingFuture) throws ExecutionException { - assertThatFutureBecomesCancelled(closingFuture.statusFuture()); - } - - @Override - void waitUntilClosed(ClosingFuture closingFuture) { - if (valueAndCloser != null) { - valueAndCloser.closeAsync(); - } - super.waitUntilClosed(closingFuture); - } - - @Override - void cancelFinalStepAndWait(ClosingFuture closingFuture) { - assertThat(closingFuture.cancel(false)).isTrue(); - ValueAndCloser unused = finishToValueAndCloser(closingFuture); - waitUntilClosed(closingFuture); - futureCancelled.countDown(); - } - - private ValueAndCloser finishToValueAndCloser(ClosingFuture closingFuture) { - final CountDownLatch valueAndCloserSet = new CountDownLatch(1); - closingFuture.finishToValueAndCloser( - new ValueAndCloserConsumer() { - @Override - public void accept(ValueAndCloser valueAndCloser) { - FinishToValueAndCloserTest.this.valueAndCloser = valueAndCloser; - valueAndCloserSet.countDown(); - } - }, - finishToValueAndCloserExecutor); - assertWithMessage("valueAndCloser was set") - .that(awaitUninterruptibly(valueAndCloserSet, 10, SECONDS)) - .isTrue(); - @SuppressWarnings("unchecked") - ValueAndCloser valueAndCloserWithType = (ValueAndCloser) valueAndCloser; - return valueAndCloserWithType; - } - } - void assertThatFutureFailsWithException(Future future) { try { getUninterruptibly(future); @@ -1822,7 +1637,7 @@ void assertThatFutureFailsWithException(Future future) { } } - private static void assertThatFutureBecomesCancelled(Future future) throws ExecutionException { + static void assertThatFutureBecomesCancelled(Future future) throws ExecutionException { try { getUninterruptibly(future); fail("Expected future to be canceled: " + future); @@ -1989,7 +1804,7 @@ void awaitReturned() { } } - private static final class NoOpValueAndCloserConsumer implements ValueAndCloserConsumer { + static final class NoOpValueAndCloserConsumer implements ValueAndCloserConsumer { @Override public void accept(ValueAndCloser valueAndCloser) {} } diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java index 557fc0b5f2fe..9b3f0f86757f 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java @@ -68,7 +68,6 @@ protected final void tearDown() { thrownByExecutionThread); } - public void testServiceStartStop() throws Exception { WaitOnRunService service = new WaitOnRunService(); assertFalse(service.startUpCalled); @@ -85,7 +84,6 @@ public void testServiceStartStop() throws Exception { executionThread.join(); } - public void testServiceStopIdempotence() throws Exception { WaitOnRunService service = new WaitOnRunService(); @@ -102,7 +100,6 @@ public void testServiceStopIdempotence() throws Exception { executionThread.join(); } - public void testServiceExitingOnItsOwn() throws Exception { WaitOnRunService service = new WaitOnRunService(); service.expectedShutdownState = Service.State.RUNNING; @@ -173,7 +170,6 @@ protected Executor executor() { } } - public void testServiceThrowOnStartUp() throws Exception { ThrowOnStartUpService service = new ThrowOnStartUpService(); assertFalse(service.startUpCalled); @@ -212,7 +208,6 @@ protected Executor executor() { } } - public void testServiceThrowOnRun() throws Exception { ThrowOnRunService service = new ThrowOnRunService(); @@ -229,7 +224,6 @@ public void testServiceThrowOnRun() throws Exception { assertEquals(Service.State.FAILED, service.state()); } - public void testServiceThrowOnRunAndThenAgainOnShutDown() throws Exception { ThrowOnRunService service = new ThrowOnRunService(); service.throwOnShutDown = true; @@ -271,7 +265,6 @@ protected Executor executor() { } } - public void testServiceThrowOnShutDown() throws Exception { ThrowOnShutDown service = new ThrowOnShutDown(); @@ -331,7 +324,6 @@ public void execute(Runnable command) {} protected void run() throws Exception {} } - public void testStopWhileStarting_runNotCalled() throws Exception { final CountDownLatch started = new CountDownLatch(1); FakeService service = @@ -361,7 +353,6 @@ public void testStop_noStart() { assertEquals(0, service.shutdownCalled); } - public void testDefaultService() throws InterruptedException { WaitOnRunService service = new WaitOnRunService(); service.startAsync().awaitRunning(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureBenchmarks.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureBenchmarks.java index bf70aac25e72..ed5e6a96db0f 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureBenchmarks.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureBenchmarks.java @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.AbstractQueuedSynchronizer; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** Utilities for the AbstractFutureBenchmarks */ final class AbstractFutureBenchmarks { @@ -218,7 +218,7 @@ public void addListener(Runnable listener, Executor exec) { * @return true if the state was successfully changed. */ @CanIgnoreReturnValue - protected boolean set(@NullableDecl V value) { + protected boolean set(@CheckForNull V value) { boolean result = sync.set(value); if (result) { executionList.execute(); @@ -360,7 +360,7 @@ boolean wasInterrupted() { } /** Transition to the COMPLETED state and set the value. */ - boolean set(@NullableDecl V v) { + boolean set(@CheckForNull V v) { return complete(v, null, COMPLETED); } @@ -384,7 +384,7 @@ boolean cancel(boolean interrupt) { * @param t the exception to set as the result of the computation. * @param finalState the state to transition to. */ - private boolean complete(@NullableDecl V v, @NullableDecl Throwable t, int finalState) { + private boolean complete(@CheckForNull V v, @CheckForNull Throwable t, int finalState) { boolean doCompletion = compareAndSetState(RUNNING, COMPLETING); if (doCompletion) { // If this thread successfully transitioned to COMPLETING, set the value @@ -406,7 +406,7 @@ private boolean complete(@NullableDecl V v, @NullableDecl Throwable t, int final } static final CancellationException cancellationExceptionWithCause( - @NullableDecl String message, @NullableDecl Throwable cause) { + @CheckForNull String message, @CheckForNull Throwable cause) { CancellationException exception = new CancellationException(message); exception.initCause(cause); return exception; diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureCancellationCauseTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureCancellationCauseTest.java index 6c921b5b67d5..9aee78029f08 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureCancellationCauseTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureCancellationCauseTest.java @@ -30,6 +30,7 @@ import junit.framework.TestCase; /** Tests for {@link AbstractFuture} with the cancellation cause system property set */ +@AndroidIncompatible // custom classloading public class AbstractFutureCancellationCauseTest extends TestCase { diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java index e55a31e725de..dc020fb20a0d 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java @@ -52,7 +52,6 @@ * * @author Brian Stoler */ - public class AbstractFutureTest extends TestCase { public void testSuccess() throws ExecutionException, InterruptedException { final Object value = new Object(); @@ -292,6 +291,7 @@ public String pendingToString() { * derived from observing how much time actually passed for various operations. */ @SuppressWarnings({"DeprecatedThreadMethods", "ThreadPriorityCheck"}) + @AndroidIncompatible // Thread.suspend public void testToString_delayedTimeout() throws Exception { TimedWaiterThread thread = new TimedWaiterThread(new AbstractFuture() {}, 2, TimeUnit.SECONDS); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java index 7cad8b0fa712..2df5a4f3afa8 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java @@ -36,7 +36,6 @@ public class AbstractIdleServiceTest extends TestCase { // Functional tests using real thread. We only verify publicly visible state. // Interaction assertions are done by the single-threaded unit tests. - public static class FunctionalTest extends TestCase { private static class DefaultService extends AbstractIdleService { diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java index 158520b932ed..a05a838692b3 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java @@ -19,8 +19,11 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.util.concurrent.AbstractScheduledService.Scheduler.newFixedDelaySchedule; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.SECONDS; +import com.google.common.util.concurrent.AbstractScheduledService.Cancellable; import com.google.common.util.concurrent.AbstractScheduledService.Scheduler; import com.google.common.util.concurrent.Service.State; import com.google.common.util.concurrent.testing.TestingExecutors; @@ -28,6 +31,7 @@ import java.util.concurrent.CancellationException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.Delayed; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; @@ -45,10 +49,9 @@ * * @author Luke Sandberg */ - public class AbstractScheduledServiceTest extends TestCase { - volatile Scheduler configuration = newFixedDelaySchedule(0, 10, TimeUnit.MILLISECONDS); + volatile Scheduler configuration = newFixedDelaySchedule(0, 10, MILLISECONDS); volatile ScheduledFuture future = null; volatile boolean atFixedRateCalled = false; @@ -111,7 +114,7 @@ public void testFailOnExceptionFromStartUp() { service.startAsync().awaitRunning(); fail(); } catch (IllegalStateException e) { - assertEquals(service.startUpException, e.getCause()); + assertThat(e).hasCauseThat().isEqualTo(service.startUpException); } assertEquals(0, service.numberOfTimesRunCalled.get()); assertEquals(Service.State.FAILED, service.state()); @@ -154,7 +157,7 @@ public void testFailOnExceptionFromShutDown() throws Exception { service.awaitTerminated(); fail(); } catch (IllegalStateException e) { - assertEquals(service.shutDownException, e.getCause()); + assertThat(e).hasCauseThat().isEqualTo(service.shutDownException); } assertEquals(Service.State.FAILED, service.state()); } @@ -206,7 +209,7 @@ protected ScheduledExecutorService executor() { @Override protected Scheduler scheduler() { - return newFixedDelaySchedule(0, 1, TimeUnit.MILLISECONDS); + return newFixedDelaySchedule(0, 1, MILLISECONDS); } }; @@ -215,7 +218,7 @@ protected Scheduler scheduler() { service.awaitRunning(); service.stopAsync(); service.awaitTerminated(); - assertTrue(executor.get().awaitTermination(100, TimeUnit.MILLISECONDS)); + assertTrue(executor.get().awaitTermination(100, MILLISECONDS)); } public void testDefaultExecutorIsShutdownWhenServiceFails() throws Exception { @@ -238,7 +241,7 @@ protected ScheduledExecutorService executor() { @Override protected Scheduler scheduler() { - return newFixedDelaySchedule(0, 1, TimeUnit.MILLISECONDS); + return newFixedDelaySchedule(0, 1, MILLISECONDS); } }; @@ -248,7 +251,7 @@ protected Scheduler scheduler() { } catch (IllegalStateException expected) { } - assertTrue(executor.get().awaitTermination(100, TimeUnit.MILLISECONDS)); + assertTrue(executor.get().awaitTermination(100, MILLISECONDS)); } public void testSchedulerOnlyCalledOnce() throws Exception { @@ -275,7 +278,7 @@ public void testTimeout() { new AbstractScheduledService() { @Override protected Scheduler scheduler() { - return Scheduler.newFixedDelaySchedule(0, 1, TimeUnit.NANOSECONDS); + return Scheduler.newFixedDelaySchedule(0, 1, NANOSECONDS); } @Override @@ -292,7 +295,7 @@ protected String serviceName() { } }; try { - service.startAsync().awaitRunning(1, TimeUnit.MILLISECONDS); + service.startAsync().awaitRunning(1, MILLISECONDS); fail("Expected timeout"); } catch (TimeoutException e) { assertThat(e) @@ -364,9 +367,9 @@ protected Scheduler scheduler() { public static class SchedulerTest extends TestCase { // These constants are arbitrary and just used to make sure that the correct method is called // with the correct parameters. - private static final int initialDelay = 10; - private static final int delay = 20; - private static final TimeUnit unit = TimeUnit.MILLISECONDS; + private static final int INITIAL_DELAY = 10; + private static final int DELAY = 20; + private static final TimeUnit UNIT = MILLISECONDS; // Unique runnable object used for comparison. final Runnable testRunnable = @@ -380,23 +383,23 @@ private void assertSingleCallWithCorrectParameters( Runnable command, long initialDelay, long delay, TimeUnit unit) { assertFalse(called); // only called once. called = true; - assertEquals(SchedulerTest.initialDelay, initialDelay); - assertEquals(SchedulerTest.delay, delay); - assertEquals(SchedulerTest.unit, unit); + assertEquals(INITIAL_DELAY, initialDelay); + assertEquals(DELAY, delay); + assertEquals(UNIT, unit); assertEquals(testRunnable, command); } public void testFixedRateSchedule() { - Scheduler schedule = Scheduler.newFixedRateSchedule(initialDelay, delay, unit); - Future unused = + Scheduler schedule = Scheduler.newFixedRateSchedule(INITIAL_DELAY, DELAY, UNIT); + Cancellable unused = schedule.schedule( null, new ScheduledThreadPoolExecutor(1) { @Override public ScheduledFuture scheduleAtFixedRate( Runnable command, long initialDelay, long period, TimeUnit unit) { - assertSingleCallWithCorrectParameters(command, initialDelay, delay, unit); - return null; + assertSingleCallWithCorrectParameters(command, initialDelay, period, unit); + return new ThrowingScheduledFuture<>(); } }, testRunnable); @@ -404,8 +407,8 @@ public ScheduledFuture scheduleAtFixedRate( } public void testFixedDelaySchedule() { - Scheduler schedule = newFixedDelaySchedule(initialDelay, delay, unit); - Future unused = + Scheduler schedule = newFixedDelaySchedule(INITIAL_DELAY, DELAY, UNIT); + Cancellable unused = schedule.schedule( null, new ScheduledThreadPoolExecutor(10) { @@ -413,13 +416,30 @@ public void testFixedDelaySchedule() { public ScheduledFuture scheduleWithFixedDelay( Runnable command, long initialDelay, long delay, TimeUnit unit) { assertSingleCallWithCorrectParameters(command, initialDelay, delay, unit); - return null; + return new ThrowingScheduledFuture<>(); } }, testRunnable); assertTrue(called); } + private static final class ThrowingScheduledFuture extends ForwardingFuture + implements ScheduledFuture { + @Override + protected Future delegate() { + throw new UnsupportedOperationException("test should not care about this"); + } + + @Override + public long getDelay(TimeUnit unit) { + throw new UnsupportedOperationException("test should not care about this"); + } + + @Override + public int compareTo(Delayed other) { + throw new UnsupportedOperationException("test should not care about this"); + } + } public void testFixedDelayScheduleFarFuturePotentiallyOverflowingScheduleIsNeverReached() throws Exception { @@ -441,7 +461,6 @@ protected Scheduler scheduler() { service.awaitTerminated(); } - public void testCustomSchedulerFarFuturePotentiallyOverflowingScheduleIsNeverReached() throws Exception { TestAbstractScheduledCustomService service = @@ -467,17 +486,16 @@ protected Schedule getNextSchedule() throws Exception { service.awaitTerminated(); } - private class TestCustomScheduler extends AbstractScheduledService.CustomScheduler { + private static class TestCustomScheduler extends AbstractScheduledService.CustomScheduler { public AtomicInteger scheduleCounter = new AtomicInteger(0); @Override protected Schedule getNextSchedule() throws Exception { scheduleCounter.incrementAndGet(); - return new Schedule(0, TimeUnit.SECONDS); + return new Schedule(0, SECONDS); } } - public void testCustomSchedule_startStop() throws Exception { final CyclicBarrier firstBarrier = new CyclicBarrier(2); final CyclicBarrier secondBarrier = new CyclicBarrier(2); @@ -497,7 +515,7 @@ public void run() { } }; TestCustomScheduler scheduler = new TestCustomScheduler(); - Future future = scheduler.schedule(null, Executors.newScheduledThreadPool(10), task); + Cancellable future = scheduler.schedule(null, Executors.newScheduledThreadPool(10), task); firstBarrier.await(); assertEquals(1, scheduler.scheduleCounter.get()); secondBarrier.await(); @@ -508,7 +526,6 @@ public void run() { future.cancel(false); } - public void testCustomSchedulerServiceStop() throws Exception { TestAbstractScheduledCustomService service = new TestAbstractScheduledCustomService(); service.startAsync().awaitRunning(); @@ -518,11 +535,10 @@ public void testCustomSchedulerServiceStop() throws Exception { service.secondBarrier.await(); service.awaitTerminated(); // Sleep for a while just to ensure that our task wasn't called again. - Thread.sleep(unit.toMillis(3 * delay)); + Thread.sleep(UNIT.toMillis(3 * DELAY)); assertEquals(1, service.numIterations.get()); } - public void testCustomScheduler_deadlock() throws InterruptedException, BrokenBarrierException { final CyclicBarrier inGetNextSchedule = new CyclicBarrier(2); // This will flakily deadlock, so run it multiple times to increase the flake likelihood @@ -542,7 +558,7 @@ protected Schedule getNextSchedule() throws Exception { Thread.yield(); throw new RuntimeException("boom"); } - return new Schedule(0, TimeUnit.NANOSECONDS); + return new Schedule(0, NANOSECONDS); } }; } @@ -553,7 +569,6 @@ protected Schedule getNextSchedule() throws Exception { } } - public void testBig() throws Exception { TestAbstractScheduledCustomService service = new TestAbstractScheduledCustomService() { @@ -564,7 +579,7 @@ protected Scheduler scheduler() { protected Schedule getNextSchedule() throws Exception { // Explicitly yield to increase the probability of a pathological scheduling. Thread.yield(); - return new Schedule(0, TimeUnit.SECONDS); + return new Schedule(0, SECONDS); } }; } @@ -607,13 +622,12 @@ protected Scheduler scheduler() { return new CustomScheduler() { @Override protected Schedule getNextSchedule() throws Exception { - return new Schedule(delay, unit); + return new Schedule(DELAY, UNIT); } }; } } - public void testCustomSchedulerFailure() throws Exception { TestFailingCustomScheduledService service = new TestFailingCustomScheduledService(); service.startAsync().awaitRunning(); @@ -624,7 +638,7 @@ public void testCustomSchedulerFailure() throws Exception { } Thread.sleep(1000); try { - service.stopAsync().awaitTerminated(100, TimeUnit.SECONDS); + service.stopAsync().awaitTerminated(100, SECONDS); fail(); } catch (IllegalStateException e) { assertEquals(State.FAILED, service.state()); @@ -657,7 +671,7 @@ protected Schedule getNextSchedule() throws Exception { if (numIterations.get() > 2) { throw new IllegalStateException("Failed"); } - return new Schedule(delay, unit); + return new Schedule(DELAY, UNIT); } }; } diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java index e3c22a8673df..5f4210621ea8 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java @@ -330,7 +330,6 @@ protected void doStop() { } } - public void testAwaitTerminated() throws Exception { final NoOpService service = new NoOpService(); Thread waiter = @@ -348,7 +347,6 @@ public void run() { assertFalse(waiter.isAlive()); } - public void testAwaitTerminated_FailedService() throws Exception { final ManualSwitchedService service = new ManualSwitchedService(); final AtomicReference exception = Atomics.newReference(); @@ -376,7 +374,6 @@ public void run() { assertThat(exception.get()).hasCauseThat().isEqualTo(EXCEPTION); } - public void testThreadedServiceStartAndWaitStopAndWait() throws Throwable { ThreadedService service = new ThreadedService(); RecordingListener listener = RecordingListener.record(service); @@ -394,7 +391,6 @@ public void testThreadedServiceStartAndWaitStopAndWait() throws Throwable { listener.getStateHistory()); } - public void testThreadedServiceStopIdempotence() throws Throwable { ThreadedService service = new ThreadedService(); @@ -410,7 +406,6 @@ public void testThreadedServiceStopIdempotence() throws Throwable { throwIfSet(thrownByExecutionThread); } - public void testThreadedServiceStopIdempotenceAfterWait() throws Throwable { ThreadedService service = new ThreadedService(); @@ -428,7 +423,6 @@ public void testThreadedServiceStopIdempotenceAfterWait() throws Throwable { throwIfSet(thrownByExecutionThread); } - public void testThreadedServiceStopIdempotenceDoubleWait() throws Throwable { ThreadedService service = new ThreadedService(); @@ -661,7 +655,6 @@ public void testFailureCause_throwsIfNotFailed() { } } - public void testAddListenerAfterFailureDoesntCauseDeadlock() throws InterruptedException { final StartFailingService service = new StartFailingService(); service.startAsync(); @@ -681,7 +674,6 @@ public void run() { assertFalse(thread + " is deadlocked", thread.isAlive()); } - public void testListenerDoesntDeadlockOnStartAndWaitFromRunning() throws Exception { final NoOpThreadedService service = new NoOpThreadedService(); service.addListener( @@ -696,7 +688,6 @@ public void running() { service.stopAsync(); } - public void testListenerDoesntDeadlockOnStopAndWaitFromTerminated() throws Exception { final NoOpThreadedService service = new NoOpThreadedService(); service.addListener( diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java index 70c186d345da..5bb1cb74e7cf 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java @@ -181,7 +181,6 @@ public void testCompareAndSet() { } /** compareAndSet in one thread enables another waiting for value to succeed */ - public void testCompareAndSetInMultipleThreads() throws InterruptedException { final AtomicDoubleArray a = new AtomicDoubleArray(1); a.set(0, 1.0); @@ -294,7 +293,6 @@ public void realRun() { * Multiple threads using same array of counters successfully update a number of times equal to * total count */ - public void testCountingInMultipleThreads() throws InterruptedException { final AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); for (int i = 0; i < SIZE; i++) { diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleTest.java index fe68e009952f..fc06fd433e11 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleTest.java @@ -13,7 +13,6 @@ package com.google.common.util.concurrent; - /** Unit test for {@link AtomicDouble}. */ public class AtomicDoubleTest extends JSR166TestCase { @@ -97,7 +96,6 @@ public void testCompareAndSet() { } /** compareAndSet in one thread enables another waiting for value to succeed */ - public void testCompareAndSetInMultipleThreads() throws Exception { final AtomicDouble at = new AtomicDouble(1.0); Thread t = diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapBasherTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapBasherTest.java index 4765825855ba..b1e741a68118 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapBasherTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapBasherTest.java @@ -16,13 +16,15 @@ package com.google.common.util.concurrent; +import static java.util.concurrent.TimeUnit.SECONDS; + import com.google.common.annotations.GwtIncompatible; +import java.util.ArrayList; import java.util.Random; +import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; import junit.framework.TestCase; /** @@ -31,29 +33,27 @@ * @author mike nonemacher */ @GwtIncompatible // threads - public class AtomicLongMapBasherTest extends TestCase { private final Random random = new Random(301); - public void testModify_basher() throws InterruptedException { + public void testModify_basher() throws Exception { int nTasks = 3000; int nThreads = 100; final int getsPerTask = 1000; final int deltaRange = 10000; final String key = "key"; - final AtomicLong sum = new AtomicLong(); final AtomicLongMap map = AtomicLongMap.create(); ExecutorService threadPool = Executors.newFixedThreadPool(nThreads); + ArrayList> futures = new ArrayList<>(); for (int i = 0; i < nTasks; i++) { - @SuppressWarnings("unused") // https://errorprone.info/bugpattern/FutureReturnValueIgnored - Future possiblyIgnoredError = + futures.add( threadPool.submit( - new Runnable() { + new Callable() { @Override - public void run() { - int threadSum = 0; + public Long call() { + long threadSum = 0; for (int j = 0; j < getsPerTask; j++) { long delta = random.nextInt(deltaRange); int behavior = random.nextInt(10); @@ -106,14 +106,16 @@ public void run() { throw new AssertionError(); } } - sum.addAndGet(threadSum); + return threadSum; } - }); + })); } - threadPool.shutdown(); - assertTrue(threadPool.awaitTermination(300, TimeUnit.SECONDS)); - - assertEquals(sum.get(), map.get(key)); + assertTrue(threadPool.awaitTermination(300, SECONDS)); + long sum = 0; + for (Future f : futures) { + sum += f.get(); + } + assertEquals(sum, map.get(key)); } } diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java index 587a4ec21d72..878ea5ec87ac 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java @@ -52,7 +52,7 @@ public void testCreate_map() { Map in = ImmutableMap.of("1", 1L, "2", 2L, "3", 3L); AtomicLongMap map = AtomicLongMap.create(in); assertFalse(map.isEmpty()); - assertSame(3, map.size()); + assertEquals(3, map.size()); assertTrue(map.containsKey("1")); assertTrue(map.containsKey("2")); assertTrue(map.containsKey("3")); @@ -302,7 +302,7 @@ public void testPutAll() { Map in = ImmutableMap.of("1", 1L, "2", 2L, "3", 3L); AtomicLongMap map = AtomicLongMap.create(); assertTrue(map.isEmpty()); - assertSame(0, map.size()); + assertEquals(0, map.size()); assertFalse(map.containsKey("1")); assertFalse(map.containsKey("2")); assertFalse(map.containsKey("3")); @@ -312,7 +312,7 @@ public void testPutAll() { map.putAll(in); assertFalse(map.isEmpty()); - assertSame(3, map.size()); + assertEquals(3, map.size()); assertTrue(map.containsKey("1")); assertTrue(map.containsKey("2")); assertTrue(map.containsKey("3")); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureFinishToFutureTest.java b/android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureFinishToFutureTest.java new file mode 100644 index 000000000000..79288eb2a0a9 --- /dev/null +++ b/android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureFinishToFutureTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2017 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.util.concurrent; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.util.concurrent.Futures.immediateFuture; +import static com.google.common.util.concurrent.MoreExecutors.directExecutor; +import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly; + +import com.google.common.util.concurrent.ClosingFuture.ClosingCallable; +import com.google.common.util.concurrent.ClosingFuture.DeferredCloser; +import java.io.Closeable; +import java.util.concurrent.ExecutionException; + +/** Tests for {@link ClosingFuture} that exercise {@link ClosingFuture#finishToFuture()}. */ +public class ClosingFutureFinishToFutureTest extends AbstractClosingFutureTest { + public void testFinishToFuture_throwsIfCalledTwice() throws Exception { + ClosingFuture closingFuture = + ClosingFuture.submit( + new ClosingCallable() { + @Override + public Closeable call(DeferredCloser closer) throws Exception { + return closer.eventuallyClose(mockCloseable, executor); + } + }, + executor); + FluentFuture unused = closingFuture.finishToFuture(); + try { + FluentFuture unused2 = closingFuture.finishToFuture(); + fail("should have thrown"); + } catch (IllegalStateException expected) { + } + } + + public void testFinishToFuture_throwsAfterCallingFinishToValueAndCloser() throws Exception { + ClosingFuture closingFuture = + ClosingFuture.submit( + new ClosingCallable() { + @Override + public Closeable call(DeferredCloser closer) throws Exception { + return closer.eventuallyClose(mockCloseable, executor); + } + }, + executor); + closingFuture.finishToValueAndCloser(new NoOpValueAndCloserConsumer<>(), directExecutor()); + try { + FluentFuture unused = closingFuture.finishToFuture(); + fail("should have thrown"); + } catch (IllegalStateException expected) { + } + } + + public void testFinishToFuture_preventsFurtherDerivation() { + ClosingFuture closingFuture = ClosingFuture.from(immediateFuture("value1")); + FluentFuture unused = closingFuture.finishToFuture(); + assertDerivingThrowsIllegalStateException(closingFuture); + } + + @Override + T getFinalValue(ClosingFuture closingFuture) throws ExecutionException { + return getUninterruptibly(closingFuture.finishToFuture()); + } + + @Override + void assertFinallyFailsWithException(ClosingFuture closingFuture) { + assertThatFutureFailsWithException(closingFuture.finishToFuture()); + } + + @Override + void assertBecomesCanceled(ClosingFuture closingFuture) throws ExecutionException { + assertThatFutureBecomesCancelled(closingFuture.finishToFuture()); + } + + @Override + void cancelFinalStepAndWait(ClosingFuture closingFuture) { + assertThat(closingFuture.finishToFuture().cancel(false)).isTrue(); + waitUntilClosed(closingFuture); + futureCancelled.countDown(); + } +} diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureFinishToValueAndCloserTest.java b/android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureFinishToValueAndCloserTest.java new file mode 100644 index 000000000000..ac3cf556925f --- /dev/null +++ b/android/guava-tests/test/com/google/common/util/concurrent/ClosingFutureFinishToValueAndCloserTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2017 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.util.concurrent; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static com.google.common.util.concurrent.MoreExecutors.shutdownAndAwaitTermination; +import static com.google.common.util.concurrent.Uninterruptibles.awaitUninterruptibly; +import static java.util.concurrent.Executors.newSingleThreadExecutor; +import static java.util.concurrent.TimeUnit.SECONDS; + +import com.google.common.util.concurrent.ClosingFuture.ClosingCallable; +import com.google.common.util.concurrent.ClosingFuture.DeferredCloser; +import com.google.common.util.concurrent.ClosingFuture.ValueAndCloser; +import com.google.common.util.concurrent.ClosingFuture.ValueAndCloserConsumer; +import java.io.Closeable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; + +/** + * Tests for {@link ClosingFuture} that exercise {@link + * ClosingFuture#finishToValueAndCloser(ValueAndCloserConsumer, Executor)}. + */ +public class ClosingFutureFinishToValueAndCloserTest extends AbstractClosingFutureTest { + private final ExecutorService finishToValueAndCloserExecutor = newSingleThreadExecutor(); + private volatile ValueAndCloser valueAndCloser; + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + assertWithMessage("finishToValueAndCloserExecutor was shut down") + .that(shutdownAndAwaitTermination(finishToValueAndCloserExecutor, 10, SECONDS)) + .isTrue(); + } + + public void testFinishToValueAndCloser_throwsIfCalledTwice() throws Exception { + ClosingFuture closingFuture = + ClosingFuture.submit( + new ClosingCallable() { + @Override + public Closeable call(DeferredCloser closer) throws Exception { + return closer.eventuallyClose(mockCloseable, executor); + } + }, + executor); + closingFuture.finishToValueAndCloser( + new NoOpValueAndCloserConsumer<>(), finishToValueAndCloserExecutor); + try { + closingFuture.finishToValueAndCloser( + new NoOpValueAndCloserConsumer<>(), finishToValueAndCloserExecutor); + fail("should have thrown"); + } catch (IllegalStateException expected) { + } + } + + public void testFinishToValueAndCloser_throwsAfterCallingFinishToFuture() throws Exception { + ClosingFuture closingFuture = + ClosingFuture.submit( + new ClosingCallable() { + @Override + public Closeable call(DeferredCloser closer) throws Exception { + return closer.eventuallyClose(mockCloseable, executor); + } + }, + executor); + FluentFuture unused = closingFuture.finishToFuture(); + try { + closingFuture.finishToValueAndCloser( + new NoOpValueAndCloserConsumer<>(), finishToValueAndCloserExecutor); + fail("should have thrown"); + } catch (IllegalStateException expected) { + } + } + + @Override + T getFinalValue(ClosingFuture closingFuture) throws ExecutionException { + return finishToValueAndCloser(closingFuture).get(); + } + + @Override + void assertFinallyFailsWithException(ClosingFuture closingFuture) { + assertThatFutureFailsWithException(closingFuture.statusFuture()); + ValueAndCloser valueAndCloser = finishToValueAndCloser(closingFuture); + try { + valueAndCloser.get(); + fail(); + } catch (ExecutionException expected) { + assertThat(expected).hasCauseThat().isSameInstanceAs(exception); + } + valueAndCloser.closeAsync(); + } + + @Override + void assertBecomesCanceled(ClosingFuture closingFuture) throws ExecutionException { + assertThatFutureBecomesCancelled(closingFuture.statusFuture()); + } + + @Override + void waitUntilClosed(ClosingFuture closingFuture) { + if (valueAndCloser != null) { + valueAndCloser.closeAsync(); + } + super.waitUntilClosed(closingFuture); + } + + @Override + void cancelFinalStepAndWait(ClosingFuture closingFuture) { + assertThat(closingFuture.cancel(false)).isTrue(); + ValueAndCloser unused = finishToValueAndCloser(closingFuture); + waitUntilClosed(closingFuture); + futureCancelled.countDown(); + } + + private ValueAndCloser finishToValueAndCloser(ClosingFuture closingFuture) { + final CountDownLatch valueAndCloserSet = new CountDownLatch(1); + closingFuture.finishToValueAndCloser( + new ValueAndCloserConsumer() { + @Override + public void accept(ValueAndCloser valueAndCloser) { + ClosingFutureFinishToValueAndCloserTest.this.valueAndCloser = valueAndCloser; + valueAndCloserSet.countDown(); + } + }, + finishToValueAndCloserExecutor); + assertWithMessage("valueAndCloser was set") + .that(awaitUninterruptibly(valueAndCloserSet, 10, SECONDS)) + .isTrue(); + @SuppressWarnings("unchecked") + ValueAndCloser valueAndCloserWithType = (ValueAndCloser) valueAndCloser; + return valueAndCloserWithType; + } +} diff --git a/android/guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java b/android/guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java index 18e69b10ee39..2b1dd2fa0881 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java @@ -442,7 +442,6 @@ public void testDifferentLockFactories_policyExecution() { lockD.lock(); } - public void testReentrantLock_tryLock() throws Exception { LockingThread thread = new LockingThread(lockA); thread.start(); @@ -454,7 +453,6 @@ public void testReentrantLock_tryLock() throws Exception { assertTrue(lockA.tryLock()); } - public void testReentrantWriteLock_tryLock() throws Exception { LockingThread thread = new LockingThread(writeLockA); thread.start(); @@ -468,7 +466,6 @@ public void testReentrantWriteLock_tryLock() throws Exception { assertTrue(readLockA.tryLock()); } - public void testReentrantReadLock_tryLock() throws Exception { LockingThread thread = new LockingThread(readLockA); thread.start(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java b/android/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java index 5bd3cf7f44da..34678ed256b8 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java @@ -36,7 +36,6 @@ public class ExecutionListTest extends TestCase { private final ExecutionList list = new ExecutionList(); - public void testRunOnPopulatedList() throws Exception { Executor exec = Executors.newCachedThreadPool(); CountDownLatch countDownLatch = new CountDownLatch(3); @@ -67,7 +66,6 @@ public void run() { assertEquals(1, runCalled.get()); } - public void testExecute_idempotentConcurrently() throws InterruptedException { final CountDownLatch okayToRun = new CountDownLatch(1); final AtomicInteger runCalled = new AtomicInteger(); @@ -103,7 +101,6 @@ public void run() { assertEquals(1, runCalled.get()); } - public void testAddAfterRun() throws Exception { // Run the previous test testRunOnPopulatedList(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ExecutionSequencerTest.java b/android/guava-tests/test/com/google/common/util/concurrent/ExecutionSequencerTest.java index 1c03f5ac4e57..068287c1986b 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/ExecutionSequencerTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/ExecutionSequencerTest.java @@ -88,7 +88,6 @@ public void testCancellationDoesNotViolateSerialization() { assertThat(thirdCallable.called).isTrue(); } - public void testCancellationMultipleThreads() throws Exception { final BlockingCallable blockingCallable = new BlockingCallable(); ListenableFuture unused = serializer.submit(blockingCallable, executor); @@ -116,7 +115,6 @@ public Boolean call() { assertThat(getDone(future2)).isFalse(); } - public void testSecondTaskWaitsForFirstEvenIfCancelled() throws Exception { final BlockingCallable blockingCallable = new BlockingCallable(); ListenableFuture future1 = serializer.submit(blockingCallable, executor); @@ -327,7 +325,6 @@ private static final class LongHolder { private static final int DIRECT_EXECUTIONS_PER_THREAD = 100; @GwtIncompatible // threads - public void testAvoidsStackOverflow_multipleThreads() throws Exception { final LongHolder holder = new LongHolder(); final ArrayList> lengthChecks = new ArrayList<>(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/FluentFutureTest.java b/android/guava-tests/test/com/google/common/util/concurrent/FluentFutureTest.java index cc4751d0f217..ab53f538307e 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/FluentFutureTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/FluentFutureTest.java @@ -132,7 +132,6 @@ public ListenableFuture apply(Integer input) { assertThat(f.get()).isEqualTo(2); } - @GwtIncompatible // withTimeout public void testWithTimeout() throws Exception { ScheduledExecutorService executor = newScheduledThreadPool(1); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java b/android/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java index 021d96de7436..84b0426a6830 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java @@ -61,7 +61,7 @@ static void testForwardingObject(final Class for new Function() { @Override public T apply(Object delegate) { - T mock = mock(forwarderClass, CALLS_REAL_METHODS.get()); + T mock = mock(forwarderClass, CALLS_REAL_METHODS); try { T stubber = doReturn(delegate).when(mock); DELEGATE_METHOD.invoke(stubber); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/FutureCallbackTest.java b/android/guava-tests/test/com/google/common/util/concurrent/FutureCallbackTest.java index 4febc5a8dcc5..5a1464d05ce7 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/FutureCallbackTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/FutureCallbackTest.java @@ -24,8 +24,8 @@ import com.google.common.annotations.GwtIncompatible; import java.util.concurrent.CancellationException; import java.util.concurrent.Executor; +import javax.annotation.CheckForNull; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; import org.mockito.Mockito; /** @@ -157,8 +157,8 @@ public void execute(Runnable command) { } private final class MockCallback implements FutureCallback { - @NullableDecl private String value = null; - @NullableDecl private Throwable failure = null; + @CheckForNull private String value = null; + @CheckForNull private Throwable failure = null; private boolean wasCalled = false; MockCallback(String expectedValue) { diff --git a/android/guava-tests/test/com/google/common/util/concurrent/FuturesGetCheckedTest.java b/android/guava-tests/test/com/google/common/util/concurrent/FuturesGetCheckedTest.java index 72b5a46564b6..666a1892982f 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/FuturesGetCheckedTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/FuturesGetCheckedTest.java @@ -353,7 +353,7 @@ public void testGetCheckedUntimed_exceptionClassUsedInitCause() { public static final class WillBeUnloadedException extends Exception {} - + @AndroidIncompatible // "Parent ClassLoader may not be null"; maybe avoidable if we try? public void testGetChecked_classUnloading() throws Exception { WeakReference classUsedByGetChecked = doTestClassUnloading(); GcFinalization.awaitClear(classUsedByGetChecked); @@ -381,5 +381,8 @@ private WeakReference doTestClassUnloading() throws Exception { * environment that forces Futures.getChecked to its fallback WeakSetValidator. One awful way of * doing so would be to derive a separate test library by using remove_from_jar to strip out * ClassValueValidator. + * + * Fortunately, we get pretty good coverage "by accident": We run all these tests against the + * *backport*, where ClassValueValidator is not present. */ } diff --git a/android/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java b/android/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java index fa3b14a26830..6fa2a32df1c7 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java @@ -53,6 +53,7 @@ import static java.util.concurrent.Executors.newSingleThreadExecutor; import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.SECONDS; import com.google.common.annotations.GwtCompatible; @@ -87,9 +88,9 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.LogRecord; import java.util.logging.Logger; +import javax.annotation.CheckForNull; import junit.framework.AssertionFailedError; import junit.framework.TestCase; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * Unit tests for {@link Futures}. @@ -410,7 +411,6 @@ public ListenableFuture apply(Foo unused) { } @GwtIncompatible // threads - public void testTransformAsync_interruptPropagatesToTransformingThread() throws Exception { SettableFuture input = SettableFuture.create(); final CountDownLatch inFunction = new CountDownLatch(1); @@ -803,7 +803,6 @@ public void testTransform_Executor() throws Exception { } @GwtIncompatible // Threads - public void testTransformAsync_functionToString() throws Exception { final CountDownLatch functionCalled = new CountDownLatch(1); final CountDownLatch functionBlocking = new CountDownLatch(1); @@ -1132,7 +1131,6 @@ public ListenableFuture apply(Throwable t) { } @GwtIncompatible // threads - public void testCatchingAsync_interruptPropagatesToTransformingThread() throws Exception { SettableFuture input = SettableFuture.create(); final CountDownLatch inFunction = new CountDownLatch(1); @@ -1172,7 +1170,6 @@ public ListenableFuture apply(Throwable t) throws Exception { } @GwtIncompatible // Threads - public void testCatchingAsync_functionToString() throws Exception { final CountDownLatch functionCalled = new CountDownLatch(1); final CountDownLatch functionBlocking = new CountDownLatch(1); @@ -1749,7 +1746,6 @@ public void testTransformAsync_asyncFunction_nullInsteadOfFuture() throws Except } @GwtIncompatible // threads - public void testTransformAsync_asyncFunction_cancelledWhileApplyingFunction() throws InterruptedException, ExecutionException { final CountDownLatch inFunction = new CountDownLatch(1); @@ -1784,7 +1780,6 @@ public ListenableFuture apply(String input) throws Exception { } @GwtIncompatible // threads - public void testTransformAsync_asyncFunction_cancelledBeforeApplyingFunction() throws InterruptedException { final AtomicBoolean functionCalled = new AtomicBoolean(); @@ -1858,7 +1853,6 @@ public void testSubmitAsync_asyncCallable_nullInsteadOfFuture() throws Exception } @GwtIncompatible // threads - public void testSubmitAsync_asyncCallable_cancelledWhileApplyingFunction() throws InterruptedException, ExecutionException { final CountDownLatch inFunction = new CountDownLatch(1); @@ -1892,7 +1886,6 @@ public ListenableFuture call() throws InterruptedException { } @GwtIncompatible // threads - public void testSubmitAsync_asyncCallable_cancelledBeforeApplyingFunction() throws InterruptedException { final AtomicBoolean callableCalled = new AtomicBoolean(); @@ -1926,7 +1919,6 @@ public void run() { } @GwtIncompatible // threads - public void testSubmitAsync_asyncCallable_returnsInterruptedFuture() throws InterruptedException { assertThat(Thread.interrupted()).isFalse(); SettableFuture cancelledFuture = SettableFuture.create(); @@ -2015,7 +2007,6 @@ public void run() { } @GwtIncompatible // threads - public void testScheduleAsync_asyncCallable_error() throws InterruptedException { final Error error = new Error("deliberate"); AsyncCallable callable = @@ -2037,14 +2028,10 @@ public ListenableFuture call() { } @GwtIncompatible // threads - public void testScheduleAsync_asyncCallable_nullInsteadOfFuture() throws Exception { ListenableFuture chainedFuture = scheduleAsync( - constantAsyncCallable(null), - 1, - TimeUnit.NANOSECONDS, - newSingleThreadScheduledExecutor()); + constantAsyncCallable(null), 1, NANOSECONDS, newSingleThreadScheduledExecutor()); try { chainedFuture.get(); fail(); @@ -2059,7 +2046,6 @@ public void testScheduleAsync_asyncCallable_nullInsteadOfFuture() throws Excepti } @GwtIncompatible // threads - public void testScheduleAsync_asyncCallable_cancelledWhileApplyingFunction() throws InterruptedException, ExecutionException { final CountDownLatch inFunction = new CountDownLatch(1); @@ -2075,7 +2061,7 @@ public ListenableFuture call() throws InterruptedException { } }; ListenableFuture future = - scheduleAsync(callable, 1, TimeUnit.NANOSECONDS, newSingleThreadScheduledExecutor()); + scheduleAsync(callable, 1, NANOSECONDS, newSingleThreadScheduledExecutor()); inFunction.await(); future.cancel(false); callableDone.countDown(); @@ -2092,7 +2078,6 @@ public ListenableFuture call() throws InterruptedException { } @GwtIncompatible // threads - public void testScheduleAsync_asyncCallable_cancelledBeforeCallingFunction() throws InterruptedException { final AtomicBoolean callableCalled = new AtomicBoolean(); @@ -2114,7 +2099,7 @@ public void run() { awaitUninterruptibly(beforeFunction); } }); - ListenableFuture future = scheduleAsync(callable, 1, TimeUnit.NANOSECONDS, executor); + ListenableFuture future = scheduleAsync(callable, 1, NANOSECONDS, executor); future.cancel(false); // Unpause the executor. @@ -2547,7 +2532,6 @@ private static String createCombinedResult(Integer i, Boolean b) { } @GwtIncompatible // threads - public void testWhenAllComplete_noLeakInterruption() throws Exception { final SettableFuture stringFuture = SettableFuture.create(); AsyncCallable combiner = @@ -2591,7 +2575,6 @@ public String call() throws Exception { } @GwtIncompatible // threads - public void testWhenAllComplete_asyncResult() throws Exception { SettableFuture futureInteger = SettableFuture.create(); SettableFuture futureBoolean = SettableFuture.create(); @@ -2683,7 +2666,6 @@ public ListenableFuture call() throws Exception { } @GwtIncompatible // threads - public void testWhenAllComplete_cancelledNotInterrupted() throws Exception { SettableFuture stringFuture = SettableFuture.create(); SettableFuture booleanFuture = SettableFuture.create(); @@ -2722,7 +2704,6 @@ public ListenableFuture call() throws Exception { } @GwtIncompatible // threads - public void testWhenAllComplete_interrupted() throws Exception { SettableFuture stringFuture = SettableFuture.create(); SettableFuture booleanFuture = SettableFuture.create(); @@ -2815,7 +2796,6 @@ public void run() { } @GwtIncompatible // threads - public void testWhenAllCompleteRunnable_resultCanceledWithoutInterrupt_doesNotInterruptRunnable() throws Exception { SettableFuture stringFuture = SettableFuture.create(); @@ -2856,7 +2836,6 @@ public void run() { } @GwtIncompatible // threads - public void testWhenAllCompleteRunnable_resultCanceledWithInterrupt_InterruptsRunnable() throws Exception { SettableFuture stringFuture = SettableFuture.create(); @@ -3375,13 +3354,11 @@ private static List conditionalPseudoTimedGetUninterruptibly( : pseudoTimedGetUninterruptibly(future, 2500, MILLISECONDS); } - @GwtIncompatible // threads public void testAllAsList_extensive() throws InterruptedException { runExtensiveMergerTest(Merger.allMerger); } - @GwtIncompatible // threads public void testSuccessfulAsList_extensive() throws InterruptedException { runExtensiveMergerTest(Merger.successMerger); @@ -3700,7 +3677,7 @@ public void testNonCancellationPropagating_doesNotPropagate() throws Exception { @GwtIncompatible // used only in GwtIncompatible tests private static class TestException extends Exception { - TestException(@NullableDecl Throwable cause) { + TestException(@CheckForNull Throwable cause) { super(cause); } } diff --git a/android/guava-tests/test/com/google/common/util/concurrent/FuturesTransformAsyncTest.java b/android/guava-tests/test/com/google/common/util/concurrent/FuturesTransformAsyncTest.java index d0fcee2384be..24990200df04 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/FuturesTransformAsyncTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/FuturesTransformAsyncTest.java @@ -131,7 +131,6 @@ public void testFutureCancellableBeforeOutputCompletion() throws Exception { } } - public void testFutureCancellableBeforeFunctionCompletion() throws Exception { // Set the result in a separate thread since this test runs the function // (which will block) in the same thread. diff --git a/android/guava-tests/test/com/google/common/util/concurrent/GeneratedMonitorTest.java b/android/guava-tests/test/com/google/common/util/concurrent/GeneratedMonitorTest.java index 872197be8b91..adeb2d1aa7c3 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/GeneratedMonitorTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/GeneratedMonitorTest.java @@ -43,7 +43,6 @@ * * @author Justin T. Sampson */ - public class GeneratedMonitorTest extends TestCase { public static TestSuite suite() { diff --git a/android/guava-tests/test/com/google/common/util/concurrent/InterruptibleMonitorTest.java b/android/guava-tests/test/com/google/common/util/concurrent/InterruptibleMonitorTest.java index 4d7a45f9c46e..bb3b43b9d16b 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/InterruptibleMonitorTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/InterruptibleMonitorTest.java @@ -22,7 +22,6 @@ * * @author Justin T. Sampson */ - public class InterruptibleMonitorTest extends MonitorTestCase { public InterruptibleMonitorTest() { diff --git a/android/guava-tests/test/com/google/common/util/concurrent/InterruptibleTaskTest.java b/android/guava-tests/test/com/google/common/util/concurrent/InterruptibleTaskTest.java index a8e098955c36..fcfe744e05ac 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/InterruptibleTaskTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/InterruptibleTaskTest.java @@ -17,13 +17,14 @@ import static com.google.common.truth.Truth.assertThat; +import java.lang.reflect.Method; import java.nio.channels.spi.AbstractInterruptibleChannel; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.AbstractOwnableSynchronizer; import java.util.concurrent.locks.LockSupport; import junit.framework.TestCase; - public final class InterruptibleTaskTest extends TestCase { // Regression test for a deadlock where a task could be stuck busy waiting for the task to @@ -52,7 +53,10 @@ String toPendingString() { } @Override - void afterRanInterruptibly(Void result, Throwable error) {} + void afterRanInterruptiblySuccess(Void result) {} + + @Override + void afterRanInterruptiblyFailure(Throwable error) {} }; Thread runner = new Thread(task); runner.start(); @@ -86,6 +90,14 @@ void doBegin() { * protect ourselves from that we want to make sure that tasks don't spin too much waiting for the * interrupting thread to complete the protocol. */ + /* + * This test hangs (or maybe is just *very* slow) under Android. + * + * TODO(b/218700094): Ideally, get this to pass under Android. Failing that, convince ourselves + * that the test isn't exposing a real problem with InterruptibleTask, one that could matter in + * prod. + */ + @AndroidIncompatible public void testInterruptIsSlow() throws Exception { final CountDownLatch isInterruptibleRegistered = new CountDownLatch(1); final SlowChannel slowChannel = new SlowChannel(); @@ -115,25 +127,38 @@ String toPendingString() { } @Override - void afterRanInterruptibly(Void result, Throwable error) {} + void afterRanInterruptiblySuccess(Void result) {} + + @Override + void afterRanInterruptiblyFailure(Throwable error) {} }; Thread runner = new Thread(task, "runner"); runner.start(); isInterruptibleRegistered.await(); // trigger the interrupt on another thread since it will block - new Thread("Interrupter") { - @Override - public void run() { - task.interruptTask(); - } - }.start(); + Thread interrupter = + new Thread("Interrupter") { + @Override + public void run() { + task.interruptTask(); + } + }; + interrupter.start(); // this will happen once the interrupt has been set which means that // 1. the runner has been woken up // 2. the interrupter is stuck in the call the Thread.interrupt() // after some period of time the runner thread should become blocked on the task because it is // waiting for the slow interrupting thread to complete Thread.interrupt - awaitBlockedOn(runner, task); + awaitBlockedOnInstanceOf(runner, InterruptibleTask.Blocker.class); + + Object blocker = LockSupport.getBlocker(runner); + assertThat(blocker).isInstanceOf(AbstractOwnableSynchronizer.class); + Method getExclusiveOwnerThread = + AbstractOwnableSynchronizer.class.getDeclaredMethod("getExclusiveOwnerThread"); + getExclusiveOwnerThread.setAccessible(true); + Thread owner = (Thread) getExclusiveOwnerThread.invoke(blocker); + assertThat(owner).isSameInstanceAs(interrupter); slowChannel.exitClose.countDown(); // release the interrupter @@ -143,8 +168,9 @@ public void run() { } // waits for the given thread to be blocked on the given object - private static void awaitBlockedOn(Thread t, Object blocker) throws InterruptedException { - while (!isThreadBlockedOn(t, blocker)) { + private static void awaitBlockedOnInstanceOf(Thread t, Class blocker) + throws InterruptedException { + while (!isThreadBlockedOnInstanceOf(t, blocker)) { if (t.getState() == Thread.State.TERMINATED) { throw new RuntimeException("Thread " + t + " exited unexpectedly"); } @@ -152,8 +178,8 @@ private static void awaitBlockedOn(Thread t, Object blocker) throws InterruptedE } } - private static boolean isThreadBlockedOn(Thread t, Object blocker) { - return t.getState() == Thread.State.WAITING && LockSupport.getBlocker(t) == blocker; + private static boolean isThreadBlockedOnInstanceOf(Thread t, Class blocker) { + return t.getState() == Thread.State.WAITING && blocker.isInstance(LockSupport.getBlocker(t)); } static final class SlowChannel extends AbstractInterruptibleChannel { diff --git a/android/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java b/android/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java index 0822ae14a8df..2f8e1b7355ac 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java @@ -675,7 +675,7 @@ void waitForThreadToEnterWaitState(Thread thread) { /** * Returns the number of milliseconds since time given by startNanoTime, which must have been - * previously returned from a call to {@link System.nanoTime()}. + * previously returned from a call to {@link System#nanoTime()}. */ long millisElapsedSince(long startNanoTime) { return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java b/android/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java index 3bb819a349fd..741ff45de8c0 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java @@ -100,7 +100,6 @@ public void testListenInPoolThreadIgnoresExecutorWhenDelegateIsDone() throws Exc assertTrue(listenableFuture.isDone()); } - public void testListenInPoolThreadUsesGivenExecutor() throws Exception { ExecutorService executorService = newCachedThreadPool(new ThreadFactoryBuilder().setDaemon(true).build()); @@ -125,7 +124,6 @@ public void testListenInPoolThreadUsesGivenExecutor() throws Exception { assertTrue(listenableFuture.isDone()); } - public void testListenInPoolThreadCustomExecutorInterrupted() throws Exception { final CountDownLatch submitSuccessful = new CountDownLatch(1); ExecutorService executorService = @@ -235,7 +233,6 @@ public synchronized void run() { } } - @SuppressWarnings("IsInstanceIncompatibleType") // intentional. public void testListenInPoolThreadRunsListenerAfterRuntimeException() throws Exception { RuntimeExceptionThrowingFuture input = new RuntimeExceptionThrowingFuture<>(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTaskTest.java b/android/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTaskTest.java index 8969a7574d04..fd51a7329fd7 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTaskTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTaskTest.java @@ -80,7 +80,6 @@ protected void tearDown() throws Exception { super.tearDown(); } - public void testListenerDoesNotRunUntilTaskCompletes() throws Exception { // Test default state of not started. @@ -106,7 +105,6 @@ public void testListenerDoesNotRunUntilTaskCompletes() throws Exception { assertFalse(task.isCancelled()); } - public void testListenerCalledOnException() throws Exception { throwException = true; @@ -142,7 +140,6 @@ public void testListenerCalledOnCancelFromNotRunning() throws Exception { assertEquals(1, runLatch.getCount()); } - public void testListenerCalledOnCancelFromRunning() throws Exception { exec.execute(task); runLatch.await(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java b/android/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java index 2dcccdb1894f..575ed06567dd 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java @@ -29,7 +29,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Used to test listenable future implementations. @@ -67,7 +67,7 @@ public void tearDown() { exec.shutdown(); } - public void testCompletedFuture(@NullableDecl Object expectedValue) + public void testCompletedFuture(@CheckForNull Object expectedValue) throws InterruptedException, ExecutionException { assertTrue(future.isDone()); assertFalse(future.isCancelled()); @@ -94,7 +94,7 @@ public void testCancelledFuture() throws InterruptedException, ExecutionExceptio } } - public void testFailedFuture(@NullableDecl String message) throws InterruptedException { + public void testFailedFuture(@CheckForNull String message) throws InterruptedException { assertTrue(future.isDone()); assertFalse(future.isCancelled()); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ListenerCallQueueTest.java b/android/guava-tests/test/com/google/common/util/concurrent/ListenerCallQueueTest.java index 5fd9b950855b..e0eb32e6a54f 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/ListenerCallQueueTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/ListenerCallQueueTest.java @@ -129,7 +129,6 @@ public void testEnqueueAndDispatch_withLabeledExceptions() { logHandler.getStoredLogRecords().get(0).getMessage()); } - public void testEnqueueAndDispatch_multithreaded() throws InterruptedException { Object listener = new Object(); ExecutorService service = Executors.newFixedThreadPool(4); @@ -153,7 +152,6 @@ public void testEnqueueAndDispatch_multithreaded() throws InterruptedException { } } - public void testEnqueueAndDispatch_multithreaded_withThrowingRunnable() throws InterruptedException { Object listener = new Object(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/MonitorTestCase.java b/android/guava-tests/test/com/google/common/util/concurrent/MonitorTestCase.java index 6d620ffc24cd..e355d35d7f81 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/MonitorTestCase.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/MonitorTestCase.java @@ -26,7 +26,6 @@ * * @author Justin T. Sampson */ - public abstract class MonitorTestCase extends TestCase { public class TestGuard extends Monitor.Guard { diff --git a/android/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java b/android/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java index fe4e7f540038..aac61735e998 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java @@ -88,7 +88,6 @@ public class MoreExecutorsTest extends JSR166TestCase { public void run() {} }; - public void testDirectExecutorServiceServiceInThreadExecution() throws Exception { final ListeningExecutorService executor = newDirectExecutorService(); final ThreadLocal threadLocalCount = @@ -168,7 +167,6 @@ public Integer call() { assertEquals(10, threadLocalCount.get().intValue()); } - public void testDirectExecutorServiceServiceTermination() throws Exception { final ExecutorService executor = newDirectExecutorService(); final CyclicBarrier barrier = new CyclicBarrier(2); @@ -259,7 +257,6 @@ public Void call() throws Exception { * Test for a bug where threads weren't getting signaled when shutdown was called, only when tasks * completed. */ - public void testDirectExecutorService_awaitTermination_missedSignal() { final ExecutorService service = MoreExecutors.newDirectExecutorService(); Thread waiter = @@ -342,6 +339,7 @@ public void testListeningDecorator() throws Exception { */ } + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testListeningDecorator_noWrapExecuteTask() { ExecutorService delegate = mock(ExecutorService.class); ListeningExecutorService service = listeningDecorator(delegate); @@ -354,7 +352,6 @@ public void run() {} verify(delegate).execute(task); } - public void testListeningDecorator_scheduleSuccess() throws Exception { final CountDownLatch completed = new CountDownLatch(1); ScheduledThreadPoolExecutor delegate = @@ -380,7 +377,6 @@ protected void afterExecute(Runnable r, Throwable t) { assertEquals(0, delegate.getQueue().size()); } - public void testListeningDecorator_scheduleFailure() throws Exception { ScheduledThreadPoolExecutor delegate = new ScheduledThreadPoolExecutor(1); ListeningScheduledExecutorService service = listeningDecorator(delegate); @@ -391,7 +387,6 @@ public void testListeningDecorator_scheduleFailure() throws Exception { assertEquals(0, delegate.getQueue().size()); } - public void testListeningDecorator_schedulePeriodic() throws Exception { ScheduledThreadPoolExecutor delegate = new ScheduledThreadPoolExecutor(1); ListeningScheduledExecutorService service = listeningDecorator(delegate); @@ -412,7 +407,6 @@ public void testListeningDecorator_schedulePeriodic() throws Exception { assertEquals(0, delegate.getQueue().size()); } - public void testListeningDecorator_cancelled() throws Exception { ScheduledThreadPoolExecutor delegate = new ScheduledThreadPoolExecutor(1); BlockingQueue delegateQueue = delegate.getQueue(); @@ -566,7 +560,7 @@ public void run() { } } - + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testAddDelayedShutdownHook_success() throws InterruptedException { TestApplication application = new TestApplication(); ExecutorService service = mock(ExecutorService.class); @@ -578,7 +572,7 @@ public void testAddDelayedShutdownHook_success() throws InterruptedException { shutdownFirst.verify(service).awaitTermination(2, TimeUnit.SECONDS); } - + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testAddDelayedShutdownHook_interrupted() throws InterruptedException { TestApplication application = new TestApplication(); ExecutorService service = mock(ExecutorService.class); @@ -588,7 +582,6 @@ public void testAddDelayedShutdownHook_interrupted() throws InterruptedException verify(service).shutdown(); } - public void testGetExitingExecutorService_executorSetToUseDaemonThreads() { TestApplication application = new TestApplication(); ThreadPoolExecutor executor = @@ -597,7 +590,7 @@ public void testGetExitingExecutorService_executorSetToUseDaemonThreads() { assertTrue(executor.getThreadFactory().newThread(EMPTY_RUNNABLE).isDaemon()); } - + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testGetExitingExecutorService_executorDelegatesToOriginal() { TestApplication application = new TestApplication(); ThreadPoolExecutor executor = mock(ThreadPoolExecutor.class); @@ -607,7 +600,7 @@ public void testGetExitingExecutorService_executorDelegatesToOriginal() { verify(executor).execute(EMPTY_RUNNABLE); } - + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testGetExitingExecutorService_shutdownHookRegistered() throws InterruptedException { TestApplication application = new TestApplication(); ThreadPoolExecutor executor = mock(ThreadPoolExecutor.class); @@ -618,7 +611,6 @@ public void testGetExitingExecutorService_shutdownHookRegistered() throws Interr verify(executor).shutdown(); } - public void testGetExitingScheduledExecutorService_executorSetToUseDaemonThreads() { TestApplication application = new TestApplication(); ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); @@ -626,7 +618,7 @@ public void testGetExitingScheduledExecutorService_executorSetToUseDaemonThreads assertTrue(executor.getThreadFactory().newThread(EMPTY_RUNNABLE).isDaemon()); } - + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testGetExitingScheduledExecutorService_executorDelegatesToOriginal() { TestApplication application = new TestApplication(); ScheduledThreadPoolExecutor executor = mock(ScheduledThreadPoolExecutor.class); @@ -636,7 +628,7 @@ public void testGetExitingScheduledExecutorService_executorDelegatesToOriginal() verify(executor).execute(EMPTY_RUNNABLE); } - + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testGetScheduledExitingExecutorService_shutdownHookRegistered() throws InterruptedException { TestApplication application = new TestApplication(); @@ -669,7 +661,6 @@ public void run() { assertEquals(oldName, Thread.currentThread().getName()); } - public void testExecutors_nullCheck() throws Exception { new ClassSanityTester() .setDefault(RateLimiter.class, RateLimiter.create(1.0)) @@ -699,14 +690,13 @@ synchronized void shutdown() throws InterruptedException { /* Half of a 1-second timeout in nanoseconds */ private static final long HALF_SECOND_NANOS = NANOSECONDS.convert(1L, SECONDS) / 2; - public void testShutdownAndAwaitTermination_immediateShutdown() throws Exception { ExecutorService service = Executors.newSingleThreadExecutor(); assertTrue(shutdownAndAwaitTermination(service, 1L, SECONDS)); assertTrue(service.isTerminated()); } - + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testShutdownAndAwaitTermination_immediateShutdownInternal() throws Exception { ExecutorService service = mock(ExecutorService.class); when(service.awaitTermination(HALF_SECOND_NANOS, NANOSECONDS)).thenReturn(true); @@ -716,7 +706,7 @@ public void testShutdownAndAwaitTermination_immediateShutdownInternal() throws E verify(service).awaitTermination(HALF_SECOND_NANOS, NANOSECONDS); } - + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testShutdownAndAwaitTermination_forcedShutDownInternal() throws Exception { ExecutorService service = mock(ExecutorService.class); when(service.awaitTermination(HALF_SECOND_NANOS, NANOSECONDS)) @@ -729,7 +719,7 @@ public void testShutdownAndAwaitTermination_forcedShutDownInternal() throws Exce verify(service).shutdownNow(); } - + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testShutdownAndAwaitTermination_nonTerminationInternal() throws Exception { ExecutorService service = mock(ExecutorService.class); when(service.awaitTermination(HALF_SECOND_NANOS, NANOSECONDS)) @@ -741,7 +731,7 @@ public void testShutdownAndAwaitTermination_nonTerminationInternal() throws Exce verify(service).shutdownNow(); } - + @AndroidIncompatible // Mocking ExecutorService is forbidden there. TODO(b/218700094): Don't mock. public void testShutdownAndAwaitTermination_interruptedInternal() throws Exception { final ExecutorService service = mock(ExecutorService.class); when(service.awaitTermination(HALF_SECOND_NANOS, NANOSECONDS)) diff --git a/android/guava-tests/test/com/google/common/util/concurrent/SequentialExecutorTest.java b/android/guava-tests/test/com/google/common/util/concurrent/SequentialExecutorTest.java index 20209e8b80dc..80e7ab2e1241 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/SequentialExecutorTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/SequentialExecutorTest.java @@ -274,7 +274,14 @@ public void run() { assertEquals(1, numCalls.get()); } - + /* + * Under Android, MyError propagates up and fails the test? + * + * TODO(b/218700094): Does this matter to prod users, or is it just a feature of our testing + * environment? If the latter, maybe write a custom Executor that avoids failing the test when it + * sees an Error? + */ + @AndroidIncompatible public void testTaskThrowsError() throws Exception { class MyError extends Error {} final CyclicBarrier barrier = new CyclicBarrier(2); @@ -313,7 +320,6 @@ public void run() { } } - public void testRejectedExecutionThrownWithMultipleCalls() throws Exception { final CountDownLatch latch = new CountDownLatch(1); final SettableFuture future = SettableFuture.create(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ServiceManagerTest.java b/android/guava-tests/test/com/google/common/util/concurrent/ServiceManagerTest.java index 2092aff52887..7db6b06aef35 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/ServiceManagerTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/ServiceManagerTest.java @@ -119,21 +119,17 @@ protected void doStop() { } } - public void testServiceStartupTimes() { Service a = new NoOpDelayedService(150); Service b = new NoOpDelayedService(353); ServiceManager serviceManager = new ServiceManager(asList(a, b)); serviceManager.startAsync().awaitHealthy(); ImmutableMap startupTimes = serviceManager.startupTimes(); - assertEquals(2, startupTimes.size()); - // TODO(kak): Use assertThat(startupTimes.get(a)).isAtLeast(150); - assertTrue(startupTimes.get(a) >= 150); - // TODO(kak): Use assertThat(startupTimes.get(b)).isAtLeast(353); - assertTrue(startupTimes.get(b) >= 353); + assertThat(startupTimes).hasSize(2); + assertThat(startupTimes.get(a)).isAtLeast(150); + assertThat(startupTimes.get(b)).isAtLeast(353); } - public void testServiceStartupTimes_selfStartingServices() { // This tests to ensure that: // 1. service times are accurate when the service is started by the manager @@ -159,9 +155,8 @@ protected void doStart() { ServiceManager serviceManager = new ServiceManager(asList(a, b)); serviceManager.startAsync().awaitHealthy(); ImmutableMap startupTimes = serviceManager.startupTimes(); - assertEquals(2, startupTimes.size()); - // TODO(kak): Use assertThat(startupTimes.get(a)).isAtLeast(150); - assertTrue(startupTimes.get(a) >= 150); + assertThat(startupTimes).hasSize(2); + assertThat(startupTimes.get(a)).isAtLeast(150); // Service b startup takes at least 353 millis, but starting the timer is delayed by at least // 150 milliseconds. so in a perfect world the timing would be 353-150=203ms, but since either // of our sleep calls can be arbitrarily delayed we should just assert that there is a time @@ -169,7 +164,6 @@ protected void doStart() { assertThat(startupTimes.get(b)).isNotNull(); } - public void testServiceStartStop() { Service a = new NoOpService(); Service b = new NoOpService(); @@ -191,7 +185,6 @@ public void testServiceStartStop() { assertTrue(listener.failedServices.isEmpty()); } - public void testFailStart() throws Exception { Service a = new NoOpService(); Service b = new FailStartService(); @@ -219,7 +212,6 @@ public void testFailStart() throws Exception { assertTrue(listener.stoppedCalled); } - public void testFailRun() throws Exception { Service a = new NoOpService(); Service b = new FailRunService(); @@ -242,7 +234,6 @@ public void testFailRun() throws Exception { assertTrue(listener.stoppedCalled); } - public void testFailStop() throws Exception { Service a = new NoOpService(); Service b = new FailStopService(); @@ -271,7 +262,6 @@ public void testToString() throws Exception { assertThat(toString).contains("FailStartService"); } - public void testTimeouts() throws Exception { Service a = new NoOpDelayedService(50); ServiceManager manager = new ServiceManager(asList(a)); @@ -448,7 +438,6 @@ public String format(LogRecord record) { * Tests that a ServiceManager can be fully shut down if one of its failure listeners is slow or * even permanently blocked. */ - public void testListenerDeadlock() throws InterruptedException { final CountDownLatch failEnter = new CountDownLatch(1); final CountDownLatch failLeave = new CountDownLatch(1); @@ -609,7 +598,6 @@ public final Throwable failureCause() { * *

    Before the bug was fixed this test would fail at least 30% of the time. */ - public void testTransitionRace() throws TimeoutException { for (int k = 0; k < 1000; k++) { List services = Lists.newArrayList(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/SettableFutureTest.java b/android/guava-tests/test/com/google/common/util/concurrent/SettableFutureTest.java index 9b8b88f27167..105e8de0410e 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/SettableFutureTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/SettableFutureTest.java @@ -51,19 +51,16 @@ public void testDefaultState() throws Exception { } } - public void testSetValue() throws Exception { assertTrue(future.set("value")); tester.testCompletedFuture("value"); } - public void testSetFailure() throws Exception { assertTrue(future.setException(new Exception("failure"))); tester.testFailedFuture("failure"); } - public void testSetFailureNull() throws Exception { try { future.setException(null); @@ -75,7 +72,6 @@ public void testSetFailureNull() throws Exception { tester.testFailedFuture("failure"); } - public void testCancel() throws Exception { assertTrue(future.cancel(true)); tester.testCancelledFuture(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java b/android/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java index 04b824f823f9..35406864dce4 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java @@ -34,7 +34,6 @@ * @author kevinb * @author Jens Nyman */ - public class SimpleTimeLimiterTest extends TestCase { private static final long DELAY_MS = 50; diff --git a/android/guava-tests/test/com/google/common/util/concurrent/StripedTest.java b/android/guava-tests/test/com/google/common/util/concurrent/StripedTest.java index fa9d87f752f2..688d6fd34ac0 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/StripedTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/StripedTest.java @@ -129,7 +129,7 @@ public void testSizes() { assertTrue(Striped.lazyWeakLock(256).size() == 256); } - + @AndroidIncompatible // Presumably GC doesn't trigger, despite our efforts. public void testWeakImplementations() { for (Striped striped : weakImplementations()) { WeakReference weakRef = new WeakReference<>(striped.get(new Object())); @@ -137,7 +137,7 @@ public void testWeakImplementations() { } } - + @AndroidIncompatible // Presumably GC doesn't trigger, despite our efforts. public void testWeakReadWrite() { Striped striped = Striped.lazyWeakReadWriteLock(1000); Object key = new Object(); @@ -150,7 +150,7 @@ public void testWeakReadWrite() { readLock.unlock(); } - + @AndroidIncompatible // Presumably GC doesn't trigger, despite our efforts. public void testStrongImplementations() { for (Striped striped : strongImplementations()) { WeakReference weakRef = new WeakReference<>(striped.get(new Object())); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/SupplementalMonitorTest.java b/android/guava-tests/test/com/google/common/util/concurrent/SupplementalMonitorTest.java index 8a52ffeed591..5b77f9a59ef5 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/SupplementalMonitorTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/SupplementalMonitorTest.java @@ -33,7 +33,6 @@ * * @author Justin T. Sampson */ - public class SupplementalMonitorTest extends TestCase { public void testLeaveWithoutEnterThrowsIMSE() { diff --git a/android/guava-tests/test/com/google/common/util/concurrent/TestThread.java b/android/guava-tests/test/com/google/common/util/concurrent/TestThread.java index 1c3c88818e4b..f85d3134dd25 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/TestThread.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/TestThread.java @@ -28,8 +28,8 @@ import java.util.concurrent.SynchronousQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import javax.annotation.CheckForNull; import junit.framework.AssertionFailedError; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; /** * A helper for concurrency testing. One or more {@code TestThread} instances are instantiated in a @@ -168,7 +168,7 @@ public void callAndAssertWaits(String methodName, Object conditionLikeObject) th * Asserts that a prior call that had caused this thread to block or wait has since returned * normally. */ - public void assertPriorCallReturns(@NullableDecl String methodName) throws Exception { + public void assertPriorCallReturns(@CheckForNull String methodName) throws Exception { assertEquals(null, getResponse(methodName).getResult()); } @@ -176,7 +176,7 @@ public void assertPriorCallReturns(@NullableDecl String methodName) throws Excep * Asserts that a prior call that had caused this thread to block or wait has since returned the * expected boolean value. */ - public void assertPriorCallReturns(boolean expected, @NullableDecl String methodName) + public void assertPriorCallReturns(boolean expected, @CheckForNull String methodName) throws Exception { assertEquals(expected, getResponse(methodName).getResult()); } diff --git a/android/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java b/android/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java index 7684b963376a..a3a7b8e79dcc 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java @@ -56,7 +56,6 @@ public void setUp() { builder = new ThreadFactoryBuilder(); } - public void testThreadFactoryBuilder_defaults() throws InterruptedException { ThreadFactory threadFactory = builder.build(); Thread thread = threadFactory.newThread(monitoredRunnable); @@ -93,7 +92,6 @@ private static void checkThreadPoolName(Thread thread, int threadId) { assertThat(thread.getName()).matches("^pool-\\d+-thread-" + threadId + "$"); } - public void testNameFormatWithPercentS_custom() { String format = "super-duper-thread-%s"; ThreadFactory factory = builder.setNameFormat(format).build(); @@ -102,7 +100,6 @@ public void testNameFormatWithPercentS_custom() { } } - public void testNameFormatWithPercentD_custom() { String format = "super-duper-thread-%d"; ThreadFactory factory = builder.setNameFormat(format).build(); @@ -111,21 +108,18 @@ public void testNameFormatWithPercentD_custom() { } } - public void testDaemon_false() { ThreadFactory factory = builder.setDaemon(false).build(); Thread thread = factory.newThread(monitoredRunnable); assertFalse(thread.isDaemon()); } - public void testDaemon_true() { ThreadFactory factory = builder.setDaemon(true).build(); Thread thread = factory.newThread(monitoredRunnable); assertTrue(thread.isDaemon()); } - public void testPriority_custom() { for (int i = Thread.MIN_PRIORITY; i <= Thread.MAX_PRIORITY; i++) { ThreadFactory factory = builder.setPriority(i).build(); @@ -150,7 +144,6 @@ public void testPriority_tooHigh() { } } - public void testUncaughtExceptionHandler_custom() { assertEquals( UNCAUGHT_EXCEPTION_HANDLER, @@ -161,7 +154,6 @@ public void testUncaughtExceptionHandler_custom() { .getUncaughtExceptionHandler()); } - public void testBuildMutateBuild() { ThreadFactory factory1 = builder.setPriority(1).build(); assertEquals(1, factory1.newThread(monitoredRunnable).getPriority()); @@ -177,7 +169,6 @@ public void testBuildTwice() { unused = builder.build(); // this is *also* allowed } - public void testBuildMutate() { ThreadFactory factory1 = builder.setPriority(1).build(); assertEquals(1, factory1.newThread(monitoredRunnable).getPriority()); @@ -186,7 +177,6 @@ public void testBuildMutate() { assertEquals(1, factory1.newThread(monitoredRunnable).getPriority()); } - public void testThreadFactory() throws InterruptedException { final String THREAD_NAME = "ludicrous speed"; final int THREAD_PRIORITY = 1; diff --git a/android/guava-tests/test/com/google/common/util/concurrent/TrustedListenableFutureTaskTest.java b/android/guava-tests/test/com/google/common/util/concurrent/TrustedListenableFutureTaskTest.java index 157afa79d8a6..e735ae02a43c 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/TrustedListenableFutureTaskTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/TrustedListenableFutureTaskTest.java @@ -84,7 +84,6 @@ public Integer call() throws Exception { } @GwtIncompatible // blocking wait - public void testCancel_interrupted() throws Exception { final AtomicBoolean interruptedExceptionThrown = new AtomicBoolean(); final CountDownLatch enterLatch = new CountDownLatch(1); @@ -135,7 +134,6 @@ public void run() { } @GwtIncompatible // blocking wait - public void testRunIdempotency() throws Exception { final int numThreads = 10; final ExecutorService executor = Executors.newFixedThreadPool(numThreads); @@ -171,7 +169,6 @@ public void run() { } @GwtIncompatible // blocking wait - public void testToString() throws Exception { final CountDownLatch enterLatch = new CountDownLatch(1); final CountDownLatch exitLatch = new CountDownLatch(1); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/UncaughtExceptionHandlersTest.java b/android/guava-tests/test/com/google/common/util/concurrent/UncaughtExceptionHandlersTest.java index eb8455b18323..4a26b4976578 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/UncaughtExceptionHandlersTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/UncaughtExceptionHandlersTest.java @@ -23,7 +23,6 @@ import junit.framework.TestCase; /** @author Gregory Kick */ - public class UncaughtExceptionHandlersTest extends TestCase { private Runtime runtimeMock; diff --git a/android/guava-tests/test/com/google/common/util/concurrent/UninterruptibleFutureTest.java b/android/guava-tests/test/com/google/common/util/concurrent/UninterruptibleFutureTest.java index 0d24266074b0..3f91b8123bd3 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/UninterruptibleFutureTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/UninterruptibleFutureTest.java @@ -77,7 +77,6 @@ protected void tearDown() { * This first test doesn't test anything in Uninterruptibles, just demonstrates some normal * behavior of futures so that you can contrast the next test with it. */ - public void testRegularFutureInterrupted() throws ExecutionException { /* @@ -116,7 +115,6 @@ public void testRegularFutureInterrupted() throws ExecutionException { assertTrue(sleeper.completed); } - public void testMakeUninterruptible_timeoutPreservedThroughInterruption() throws ExecutionException { @@ -155,32 +153,26 @@ public void run() { } } - public void testMakeUninterruptible_untimed_uninterrupted() throws Exception { runUntimedInterruptsTest(0); } - public void testMakeUninterruptible_untimed_interrupted() throws Exception { runUntimedInterruptsTest(1); } - public void testMakeUninterruptible_untimed_multiplyInterrupted() throws Exception { runUntimedInterruptsTest(38); } - public void testMakeUninterruptible_timed_uninterrupted() throws Exception { runTimedInterruptsTest(0); } - public void testMakeUninterruptible_timed_interrupted() throws Exception { runTimedInterruptsTest(1); } - public void testMakeUninterruptible_timed_multiplyInterrupted() throws Exception { runTimedInterruptsTest(38); } @@ -218,7 +210,6 @@ private static void runNInterruptsTest( /** * Confirms that the test code triggers {@link InterruptedException} in a standard {@link Future}. */ - public void testMakeUninterruptible_plainFutureSanityCheck() throws Exception { SettableFuture future = SettableFuture.create(); FutureTask wasInterrupted = untimedInterruptReporter(future, true); @@ -235,7 +226,6 @@ public void testMakeUninterruptible_plainFutureSanityCheck() throws Exception { } } - public void testMakeUninterruptible_timedGetZeroTimeoutAttempted() throws TimeoutException, ExecutionException { SettableFuture future = SettableFuture.create(); @@ -248,7 +238,6 @@ public void testMakeUninterruptible_timedGetZeroTimeoutAttempted() assertEquals(RESULT, getUninterruptibly(future, 0, SECONDS)); } - public void testMakeUninterruptible_timedGetNegativeTimeoutAttempted() throws TimeoutException, ExecutionException { SettableFuture future = SettableFuture.create(); diff --git a/android/guava-tests/test/com/google/common/util/concurrent/UninterruptibleMonitorTest.java b/android/guava-tests/test/com/google/common/util/concurrent/UninterruptibleMonitorTest.java index 59bf80878849..3e775bab5676 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/UninterruptibleMonitorTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/UninterruptibleMonitorTest.java @@ -22,7 +22,6 @@ * * @author Justin T. Sampson */ - public class UninterruptibleMonitorTest extends MonitorTestCase { public UninterruptibleMonitorTest() { diff --git a/android/guava-tests/test/com/google/common/util/concurrent/UninterruptiblesTest.java b/android/guava-tests/test/com/google/common/util/concurrent/UninterruptiblesTest.java index e58cf6a60ef1..ab8d5b0a8bc2 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/UninterruptiblesTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/UninterruptiblesTest.java @@ -54,7 +54,6 @@ * * @author Anthony Zana */ - public class UninterruptiblesTest extends TestCase { private static final String EXPECTED_TAKE = "expectedTake"; diff --git a/android/guava/pom.xml b/android/guava/pom.xml index 5deda6e057fc..39611d4c9e3b 100644 --- a/android/guava/pom.xml +++ b/android/guava/pom.xml @@ -5,11 +5,12 @@ com.google.guava guava-parent - HEAD-android-SNAPSHOT + 31.1-android guava bundle Guava: Google Core Libraries for Java + https://github.com/google/guava Guava is a suite of core and expanded libraries that include utility classes, Google's collections, I/O classes, and @@ -32,7 +33,7 @@ org.checkerframework - checker-compat-qual + checker-qual com.google.errorprone @@ -90,42 +91,6 @@ maven-compiler-plugin - - - - default-compile - compile - - compile - - - - **/Java8Usage.java - - - 8 - 8 - - - - main-compile - compile - - compile - - - - **/Java8Usage.java - - - - maven-source-plugin @@ -164,7 +129,7 @@ - com.google.common.base.internal,com.google.common.base.internal.*,com.google.thirdparty.publicsuffix,com.google.thirdparty.publicsuffix.*,com.oracle.*,com.sun.*,java.*,javax.*,jdk,jdk.*,org.*,sun.* + com.azul.tooling.in,com.google.common.base.internal,com.google.common.base.internal.*,com.google.thirdparty.publicsuffix,com.google.thirdparty.publicsuffix.*,com.oracle.*,com.sun.*,java.*,javax.*,jdk,jdk.*,org.*,sun.* diff --git a/android/guava/src/com/google/common/base/Absent.java b/android/guava/src/com/google/common/base/Absent.java index 86aec0516d26..f96136b5efac 100644 --- a/android/guava/src/com/google/common/base/Absent.java +++ b/android/guava/src/com/google/common/base/Absent.java @@ -19,10 +19,11 @@ import com.google.common.annotations.GwtCompatible; import java.util.Collections; import java.util.Set; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** Implementation of an {@link Optional} not containing a reference. */ @GwtCompatible +@ElementTypesAreNonnullByDefault final class Absent extends Optional { static final Absent INSTANCE = new Absent<>(); @@ -61,7 +62,7 @@ public T or(Supplier supplier) { } @Override - @NullableDecl + @CheckForNull public T orNull() { return null; } @@ -78,7 +79,7 @@ public Optional transform(Function function) { } @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { return object == this; } diff --git a/android/guava/src/com/google/common/base/AbstractIterator.java b/android/guava/src/com/google/common/base/AbstractIterator.java index f6f521e904a5..bb0a1d324978 100644 --- a/android/guava/src/com/google/common/base/AbstractIterator.java +++ b/android/guava/src/com/google/common/base/AbstractIterator.java @@ -14,20 +14,23 @@ package com.google.common.base; +import static com.google.common.base.NullnessCasts.uncheckedCastNullableTToT; import static com.google.common.base.Preconditions.checkState; import com.google.common.annotations.GwtCompatible; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.util.Iterator; import java.util.NoSuchElementException; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Note this class is a copy of {@link com.google.common.collect.AbstractIterator} (for dependency * reasons). */ @GwtCompatible -abstract class AbstractIterator implements Iterator { +@ElementTypesAreNonnullByDefault +abstract class AbstractIterator implements Iterator { private State state = State.NOT_READY; protected AbstractIterator() {} @@ -39,12 +42,13 @@ private enum State { FAILED, } - @NullableDecl private T next; + @CheckForNull private T next; + @CheckForNull protected abstract T computeNext(); @CanIgnoreReturnValue - @NullableDecl + @CheckForNull protected final T endOfData() { state = State.DONE; return null; @@ -74,12 +78,14 @@ private boolean tryToComputeNext() { } @Override + @ParametricNullness public final T next() { if (!hasNext()) { throw new NoSuchElementException(); } state = State.NOT_READY; - T result = next; + // Safe because hasNext() ensures that tryToComputeNext() has put a T into `next`. + T result = uncheckedCastNullableTToT(next); next = null; return result; } diff --git a/android/guava/src/com/google/common/base/Ascii.java b/android/guava/src/com/google/common/base/Ascii.java index 3a9558016de4..0c651bb27be4 100644 --- a/android/guava/src/com/google/common/base/Ascii.java +++ b/android/guava/src/com/google/common/base/Ascii.java @@ -37,6 +37,7 @@ * @since 7.0 */ @GwtCompatible +@ElementTypesAreNonnullByDefault public final class Ascii { private Ascii() {} @@ -439,7 +440,7 @@ public static String toLowerCase(CharSequence chars) { } /** - * If the argument is an {@linkplain #isUpperCase(char) uppercase ASCII character} returns the + * If the argument is an {@linkplain #isUpperCase(char) uppercase ASCII character}, returns the * lowercase equivalent. Otherwise returns the argument. */ public static char toLowerCase(char c) { @@ -487,7 +488,7 @@ public static String toUpperCase(CharSequence chars) { } /** - * If the argument is a {@linkplain #isLowerCase(char) lowercase ASCII character} returns the + * If the argument is a {@linkplain #isLowerCase(char) lowercase ASCII character}, returns the * uppercase equivalent. Otherwise returns the argument. */ public static char toUpperCase(char c) { diff --git a/android/guava/src/com/google/common/base/CaseFormat.java b/android/guava/src/com/google/common/base/CaseFormat.java index 5e24bc901b63..7b393ebd7e0f 100644 --- a/android/guava/src/com/google/common/base/CaseFormat.java +++ b/android/guava/src/com/google/common/base/CaseFormat.java @@ -15,10 +15,11 @@ package com.google.common.base; import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.requireNonNull; import com.google.common.annotations.GwtCompatible; import java.io.Serializable; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Utility class for converting between various ASCII case formats. Behavior is undefined for @@ -28,6 +29,7 @@ * @since 1.0 */ @GwtCompatible +@ElementTypesAreNonnullByDefault public enum CaseFormat { /** Hyphenated variable naming convention, e.g., "lower-hyphen". */ LOWER_HYPHEN(CharMatcher.is('-'), "-") { @@ -138,14 +140,14 @@ String convert(CaseFormat format, String s) { out = new StringBuilder(s.length() + 4 * format.wordSeparator.length()); out.append(format.normalizeFirstWord(s.substring(i, j))); } else { - out.append(format.normalizeWord(s.substring(i, j))); + requireNonNull(out).append(format.normalizeWord(s.substring(i, j))); } out.append(format.wordSeparator); i = j + wordSeparator.length(); } return (i == 0) ? format.normalizeFirstWord(s) - : out.append(format.normalizeWord(s.substring(i))).toString(); + : requireNonNull(out).append(format.normalizeWord(s.substring(i))).toString(); } /** @@ -179,7 +181,7 @@ protected String doBackward(String s) { } @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { if (object instanceof StringConverter) { StringConverter that = (StringConverter) object; return sourceFormat.equals(that.sourceFormat) && targetFormat.equals(that.targetFormat); diff --git a/android/guava/src/com/google/common/base/CharMatcher.java b/android/guava/src/com/google/common/base/CharMatcher.java index e17db17dad12..2a2a89447890 100644 --- a/android/guava/src/com/google/common/base/CharMatcher.java +++ b/android/guava/src/com/google/common/base/CharMatcher.java @@ -61,6 +61,7 @@ * @since 1.0 */ @GwtCompatible(emulated = true) +@ElementTypesAreNonnullByDefault public abstract class CharMatcher implements Predicate { /* * N777777777NO @@ -1460,10 +1461,10 @@ private static final class Invisible extends RangesMatcher { // [[[:Zs:][:Zl:][:Zp:][:Cc:][:Cf:][:Cs:][:Co:]]&[\u0000-\uFFFF]] // with the "Abbreviate" option, and get the ranges from there. private static final String RANGE_STARTS = - "\u0000\u007f\u00ad\u0600\u061c\u06dd\u070f\u08e2\u1680\u180e\u2000\u2028\u205f\u2066" + "\u0000\u007f\u00ad\u0600\u061c\u06dd\u070f\u0890\u08e2\u1680\u180e\u2000\u2028\u205f\u2066" + "\u3000\ud800\ufeff\ufff9"; private static final String RANGE_ENDS = // inclusive ends - "\u0020\u00a0\u00ad\u0605\u061c\u06dd\u070f\u08e2\u1680\u180e\u200f\u202f\u2064\u206f" + "\u0020\u00a0\u00ad\u0605\u061c\u06dd\u070f\u0891\u08e2\u1680\u180e\u200f\u202f\u2064\u206f" + "\u3000\uf8ff\ufeff\ufffb"; static final Invisible INSTANCE = new Invisible(); diff --git a/android/guava/src/com/google/common/base/Charsets.java b/android/guava/src/com/google/common/base/Charsets.java index 2c9563d769c8..7aebea826c78 100644 --- a/android/guava/src/com/google/common/base/Charsets.java +++ b/android/guava/src/com/google/common/base/Charsets.java @@ -31,6 +31,7 @@ * @since 1.0 */ @GwtCompatible(emulated = true) +@ElementTypesAreNonnullByDefault public final class Charsets { private Charsets() {} diff --git a/android/guava/src/com/google/common/base/CommonMatcher.java b/android/guava/src/com/google/common/base/CommonMatcher.java index 6d14c6bc2630..d63b46b5d48f 100644 --- a/android/guava/src/com/google/common/base/CommonMatcher.java +++ b/android/guava/src/com/google/common/base/CommonMatcher.java @@ -22,6 +22,7 @@ * javadoc for details. */ @GwtCompatible +@ElementTypesAreNonnullByDefault abstract class CommonMatcher { public abstract boolean matches(); diff --git a/android/guava/src/com/google/common/base/CommonPattern.java b/android/guava/src/com/google/common/base/CommonPattern.java index 6be5b01408aa..c425d52609d6 100644 --- a/android/guava/src/com/google/common/base/CommonPattern.java +++ b/android/guava/src/com/google/common/base/CommonPattern.java @@ -22,6 +22,7 @@ * javadoc for details. */ @GwtCompatible +@ElementTypesAreNonnullByDefault abstract class CommonPattern { public abstract CommonMatcher matcher(CharSequence t); diff --git a/android/guava/src/com/google/common/base/Converter.java b/android/guava/src/com/google/common/base/Converter.java index ea86bb69fde5..422480d164a2 100644 --- a/android/guava/src/com/google/common/base/Converter.java +++ b/android/guava/src/com/google/common/base/Converter.java @@ -14,16 +14,19 @@ package com.google.common.base; +import static com.google.common.base.NullnessCasts.uncheckedCastNullableTToT; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.annotations.GwtCompatible; import com.google.errorprone.annotations.CanIgnoreReturnValue; +import com.google.errorprone.annotations.CheckReturnValue; import com.google.errorprone.annotations.ForOverride; +import com.google.errorprone.annotations.InlineMe; import com.google.errorprone.annotations.concurrent.LazyInit; import com.google.j2objc.annotations.RetainedWith; import java.io.Serializable; import java.util.Iterator; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * A function from {@code A} to {@code B} with an associated reverse function from {@code B} @@ -113,11 +116,36 @@ * @since 16.0 */ @GwtCompatible +@ElementTypesAreNonnullByDefault +/* + * 1. The type parameter is rather than so that we can use T in the + * doForward and doBackward methods to indicate that the parameter cannot be null. (We also take + * advantage of that for convertAll, as discussed on that method.) + * + * 2. The supertype of this class could be `Function<@Nullable A, @Nullable B>`, since + * Converter.apply (like Converter.convert) is capable of accepting null inputs. However, a + * supertype of `Function` turns out to be massively more useful to callers in practice: They + * want their output to be non-null in operations like `stream.map(myConverter)`, and we can + * guarantee that as long as we also require the input type to be non-null[*] (which is a + * requirement that existing callers already fulfill). + * + * Disclaimer: Part of the reason that callers are so well adapted to `Function` may be that + * that is how the signature looked even prior to this comment! So naturally any change can break + * existing users, but it can't *fix* existing users because any users who needed + * `Function<@Nullable A, @Nullable B>` already had to find a workaround. Still, there is a *ton* of + * fallout from trying to switch. I would be shocked if the switch would offer benefits to anywhere + * near enough users to justify the costs. + * + * Fortunately, if anyone does want to use a Converter as a `Function<@Nullable A, @Nullable B>`, + * it's easy to get one: `converter::convert`. + * + * [*] In annotating this class, we're ignoring LegacyConverter. + */ public abstract class Converter implements Function { private final boolean handleNullAutomatically; // We lazily cache the reverse view to avoid allocating on every call to reverse(). - @LazyInit @RetainedWith @NullableDecl private transient Converter reverse; + @LazyInit @RetainedWith @CheckForNull private transient Converter reverse; /** Constructor for use by subclasses. */ protected Converter() { @@ -164,31 +192,67 @@ protected Converter() { * @return the converted value; is null if and only if {@code a} is null */ @CanIgnoreReturnValue - @NullableDecl - public final B convert(@NullableDecl A a) { + @CheckForNull + public final B convert(@CheckForNull A a) { return correctedDoForward(a); } - @NullableDecl - B correctedDoForward(@NullableDecl A a) { + @CheckForNull + B correctedDoForward(@CheckForNull A a) { if (handleNullAutomatically) { // TODO(kevinb): we shouldn't be checking for a null result at runtime. Assert? return a == null ? null : checkNotNull(doForward(a)); } else { - return doForward(a); + return unsafeDoForward(a); } } - @NullableDecl - A correctedDoBackward(@NullableDecl B b) { + @CheckForNull + A correctedDoBackward(@CheckForNull B b) { if (handleNullAutomatically) { // TODO(kevinb): we shouldn't be checking for a null result at runtime. Assert? return b == null ? null : checkNotNull(doBackward(b)); } else { - return doBackward(b); + return unsafeDoBackward(b); } } + /* + * LegacyConverter violates the contract of Converter by allowing its doForward and doBackward + * methods to accept null. We could avoid having unchecked casts in Converter.java itself if we + * could perform a cast to LegacyConverter, but we can't because it's an internal-only class. + * + * TODO(cpovirk): So make it part of the open-source build, albeit package-private there? + * + * So we use uncheckedCastNullableTToT here. This is a weird usage of that method: The method is + * documented as being for use with type parameters that have parametric nullness. But Converter's + * type parameters do not. Still, we use it here so that we can suppress a warning at a smaller + * level than the whole method but without performing a runtime null check. That way, we can still + * pass null inputs to LegacyConverter, and it can violate the contract of Converter. + * + * TODO(cpovirk): Could this be simplified if we modified implementations of LegacyConverter to + * override methods (probably called "unsafeDoForward" and "unsafeDoBackward") with the same + * signatures as the methods below, rather than overriding the same doForward and doBackward + * methods as implementations of normal converters do? + * + * But no matter what we do, it's worth remembering that the resulting code is going to be unsound + * in the presence of LegacyConverter, at least in the case of users who view the converter as a + * Function or who call convertAll (and for any checkers that apply @PolyNull-like semantics + * to Converter.convert). So maybe we don't want to think too hard about how to prevent our + * checkers from issuing errors related to LegacyConverter, since it turns out that + * LegacyConverter does violate the assumptions we make elsewhere. + */ + + @CheckForNull + private B unsafeDoForward(@CheckForNull A a) { + return doForward(uncheckedCastNullableTToT(a)); + } + + @CheckForNull + private A unsafeDoBackward(@CheckForNull B b) { + return doBackward(uncheckedCastNullableTToT(b)); + } + /** * Returns an iterable that applies {@code convert} to each element of {@code fromIterable}. The * conversion is done lazily. @@ -198,7 +262,17 @@ A correctedDoBackward(@NullableDecl B b) { * element. */ @CanIgnoreReturnValue - public Iterable convertAll(final Iterable fromIterable) { + /* + * Just as Converter could implement `Function<@Nullable A, @Nullable B>` instead of `Function`, convertAll could accept and return iterables with nullable element types. In both cases, + * we've chosen to instead use a signature that benefits existing users -- and is still safe. + * + * For convertAll, I haven't looked as closely at *how* much existing users benefit, so we should + * keep an eye out for problems that new users encounter. Note also that convertAll could support + * both use cases by using @PolyNull. (By contrast, we can't use @PolyNull for our superinterface + * (`implements Function<@PolyNull A, @PolyNull B>`), at least as far as I know.) + */ + public Iterable convertAll(Iterable fromIterable) { checkNotNull(fromIterable, "fromIterable"); return new Iterable() { @Override @@ -212,6 +286,8 @@ public boolean hasNext() { } @Override + @SuppressWarnings("nullness") // See code comments on convertAll and Converter.apply. + @CheckForNull public B next() { return convert(fromIterator.next()); } @@ -233,7 +309,7 @@ public void remove() { * *

    Note: you should not override this method. It is non-final for legacy reasons. */ - @CanIgnoreReturnValue + @CheckReturnValue public Converter reverse() { Converter result = reverse; return (result == null) ? reverse = new ReverseConverter<>(this) : result; @@ -265,14 +341,14 @@ protected B doBackward(A a) { } @Override - @NullableDecl - A correctedDoForward(@NullableDecl B b) { + @CheckForNull + A correctedDoForward(@CheckForNull B b) { return original.correctedDoBackward(b); } @Override - @NullableDecl - B correctedDoBackward(@NullableDecl A a) { + @CheckForNull + B correctedDoBackward(@CheckForNull A a) { return original.correctedDoForward(a); } @@ -282,7 +358,7 @@ public Converter reverse() { } @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { if (object instanceof ReverseConverter) { ReverseConverter that = (ReverseConverter) object; return this.original.equals(that.original); @@ -347,19 +423,19 @@ protected A doBackward(C c) { } @Override - @NullableDecl - C correctedDoForward(@NullableDecl A a) { + @CheckForNull + C correctedDoForward(@CheckForNull A a) { return second.correctedDoForward(first.correctedDoForward(a)); } @Override - @NullableDecl - A correctedDoBackward(@NullableDecl C c) { + @CheckForNull + A correctedDoBackward(@CheckForNull C c) { return first.correctedDoBackward(second.correctedDoBackward(c)); } @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { if (object instanceof ConverterComposition) { ConverterComposition that = (ConverterComposition) object; return this.first.equals(that.first) && this.second.equals(that.second); @@ -386,8 +462,40 @@ public String toString() { @Deprecated @Override @CanIgnoreReturnValue - @NullableDecl - public final B apply(@NullableDecl A a) { + /* + * Even though we implement `Function` instead of `Function<@Nullable A, @Nullable B>` (as + * discussed in a code comment at the top of the class), we declare our override of Function.apply + * to accept and return null. This requires a suppression, but it's safe: + * + * - Callers who use Converter as a Function will neither pass null nor have it returned to + * them. (Or, if they're not using nullness checking, they might be able to pass null and thus + * have null returned to them. But our signature isn't making their existing nullness type error + * any worse.) + * - In the relatively unlikely event that anyone calls Converter.apply directly, that caller is + * allowed to pass null but is also forced to deal with a potentially null return. + * - Perhaps more important than actual *callers* of this method are various tools that look at + * bytecode. Notably, NullPointerTester expects a method to throw NPE when passed null unless it + * is annotated in a way that identifies its parameter type as potentially including null. (And + * this method does not throw NPE -- nor do we want to enact a dangerous change to make it begin + * doing so.) We can even imagine tools that rewrite bytecode to insert null checks before and + * after calling methods with allegedly non-nullable parameters[*]. If we didn't annotate the + * parameter and return type here, then anyone who used such a tool (and managed to pass null to + * this method, presumably because that user doesn't run a normal nullness checker) could see + * NullPointerException. + * + * [*] Granted, such tools could conceivably be smart enough to recognize that the apply() method + * on a a Function should never allow null inputs and never produce null outputs even if + * this specific subclass claims otherwise. Such tools might still produce NPE for calls to this + * method. And that is one reason that we should be nervous about "lying" by extending Function in the first place. But for now, we're giving it a try, since extending Function<@Nullable + * A, @Nullable B> will cause issues *today*, whereas extending Function causes problems in + * various hypothetical futures. (Plus, a tool that were that smart would likely already introduce + * problems with LegacyConverter.) + */ + @SuppressWarnings("nullness") + @CheckForNull + @InlineMe(replacement = "this.convert(a)") + public final B apply(@CheckForNull A a) { return convert(a); } @@ -403,7 +511,7 @@ public final B apply(@NullableDecl A a) { * interchangeable. */ @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { return super.equals(object); } @@ -452,7 +560,7 @@ protected A doBackward(B b) { } @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { if (object instanceof FunctionBasedConverter) { FunctionBasedConverter that = (FunctionBasedConverter) object; return this.forwardFunction.equals(that.forwardFunction) diff --git a/android/guava/src/com/google/common/base/Defaults.java b/android/guava/src/com/google/common/base/Defaults.java index 00adbdefa12f..5d12343ed241 100644 --- a/android/guava/src/com/google/common/base/Defaults.java +++ b/android/guava/src/com/google/common/base/Defaults.java @@ -17,7 +17,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.annotations.GwtIncompatible; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * This class provides default values for all Java types, as defined by the JLS. @@ -26,11 +26,12 @@ * @since 1.0 */ @GwtIncompatible +@ElementTypesAreNonnullByDefault public final class Defaults { private Defaults() {} - private static final Double DOUBLE_DEFAULT = Double.valueOf(0d); - private static final Float FLOAT_DEFAULT = Float.valueOf(0f); + private static final Double DOUBLE_DEFAULT = 0d; + private static final Float FLOAT_DEFAULT = 0f; /** * Returns the default value of {@code type} as defined by JLS --- {@code 0} for numbers, {@code @@ -38,27 +39,28 @@ private Defaults() {} * {@code void}, {@code null} is returned. */ @SuppressWarnings("unchecked") - @NullableDecl + @CheckForNull public static T defaultValue(Class type) { checkNotNull(type); - if (type == boolean.class) { - return (T) Boolean.FALSE; - } else if (type == char.class) { - return (T) Character.valueOf('\0'); - } else if (type == byte.class) { - return (T) Byte.valueOf((byte) 0); - } else if (type == short.class) { - return (T) Short.valueOf((short) 0); - } else if (type == int.class) { - return (T) Integer.valueOf(0); - } else if (type == long.class) { - return (T) Long.valueOf(0L); - } else if (type == float.class) { - return (T) FLOAT_DEFAULT; - } else if (type == double.class) { - return (T) DOUBLE_DEFAULT; - } else { - return null; + if (type.isPrimitive()) { + if (type == boolean.class) { + return (T) Boolean.FALSE; + } else if (type == char.class) { + return (T) Character.valueOf('\0'); + } else if (type == byte.class) { + return (T) Byte.valueOf((byte) 0); + } else if (type == short.class) { + return (T) Short.valueOf((short) 0); + } else if (type == int.class) { + return (T) Integer.valueOf(0); + } else if (type == long.class) { + return (T) Long.valueOf(0L); + } else if (type == float.class) { + return (T) FLOAT_DEFAULT; + } else if (type == double.class) { + return (T) DOUBLE_DEFAULT; + } } + return null; } } diff --git a/android/guava/src/com/google/common/base/ElementTypesAreNonnullByDefault.java b/android/guava/src/com/google/common/base/ElementTypesAreNonnullByDefault.java new file mode 100644 index 000000000000..890e3a36062a --- /dev/null +++ b/android/guava/src/com/google/common/base/ElementTypesAreNonnullByDefault.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.base; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.google.common.annotations.GwtCompatible; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import javax.annotation.Nonnull; +import javax.annotation.meta.TypeQualifierDefault; + +/** + * Marks all "top-level" types as non-null in a way that is recognized by Kotlin. Note that this + * unfortunately includes type-variable usages, so we also provide {@link ParametricNullness} to + * "undo" it as best we can. + */ +@GwtCompatible +@Retention(RUNTIME) +@Target(TYPE) +@TypeQualifierDefault({FIELD, METHOD, PARAMETER}) +@Nonnull +@interface ElementTypesAreNonnullByDefault {} diff --git a/android/guava/src/com/google/common/base/Enums.java b/android/guava/src/com/google/common/base/Enums.java index 247fa6ed2ecf..5c55b65942cd 100644 --- a/android/guava/src/com/google/common/base/Enums.java +++ b/android/guava/src/com/google/common/base/Enums.java @@ -25,7 +25,7 @@ import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Utility methods for working with {@link Enum} instances. @@ -34,6 +34,7 @@ * @since 9.0 */ @GwtCompatible(emulated = true) +@ElementTypesAreNonnullByDefault public final class Enums { private Enums() {} @@ -104,8 +105,8 @@ static > Map>> getEnum * * @since 16.0 */ - public static > Converter stringConverter(final Class enumClass) { - return new StringConverter(enumClass); + public static > Converter stringConverter(Class enumClass) { + return new StringConverter<>(enumClass); } private static final class StringConverter> extends Converter @@ -128,7 +129,7 @@ protected String doBackward(T enumValue) { } @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { if (object instanceof StringConverter) { StringConverter that = (StringConverter) object; return this.enumClass.equals(that.enumClass); diff --git a/android/guava/src/com/google/common/base/Equivalence.java b/android/guava/src/com/google/common/base/Equivalence.java index 436444839f48..1bf7f98998f2 100644 --- a/android/guava/src/com/google/common/base/Equivalence.java +++ b/android/guava/src/com/google/common/base/Equivalence.java @@ -19,7 +19,8 @@ import com.google.common.annotations.GwtCompatible; import com.google.errorprone.annotations.ForOverride; import java.io.Serializable; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * A strategy for determining whether two instances are considered equivalent, and for computing @@ -38,6 +39,11 @@ * source-compatible since 4.0) */ @GwtCompatible +@ElementTypesAreNonnullByDefault +/* + * The type parameter is rather than so that we can use T in the + * doEquivalent and doHash methods to indicate that the parameter cannot be null. + */ public abstract class Equivalence { /** Constructor for use by subclasses. */ protected Equivalence() {} @@ -59,7 +65,7 @@ protected Equivalence() {} *

    Note that all calls to {@code equivalent(x, y)} are expected to return the same result as * long as neither {@code x} nor {@code y} is modified. */ - public final boolean equivalent(@NullableDecl T a, @NullableDecl T b) { + public final boolean equivalent(@CheckForNull T a, @CheckForNull T b) { if (a == b) { return true; } @@ -70,8 +76,6 @@ public final boolean equivalent(@NullableDecl T a, @NullableDecl T b) { } /** - * This method should not be called except by {@link #equivalent}. When {@link #equivalent} calls - * this method, {@code a} and {@code b} are guaranteed to be distinct, non-null instances. * * @since 10.0 (previously, subclasses would override equivalent()) */ @@ -95,7 +99,7 @@ public final boolean equivalent(@NullableDecl T a, @NullableDecl T b) { *

  • {@code hash(null)} is {@code 0}. * */ - public final int hash(@NullableDecl T t) { + public final int hash(@CheckForNull T t) { if (t == null) { return 0; } @@ -137,7 +141,7 @@ public final int hash(@NullableDecl T t) { * * @since 10.0 */ - public final Equivalence onResultOf(Function function) { + public final Equivalence onResultOf(Function function) { return new FunctionalEquivalence<>(function, this); } @@ -148,8 +152,44 @@ public final Equivalence onResultOf(Function function) { * * @since 10.0 */ - public final Wrapper wrap(@NullableDecl S reference) { - return new Wrapper(this, reference); + public final Wrapper wrap(@ParametricNullness S reference) { + /* + * I'm pretty sure that this warning "makes sense" but doesn't indicate a real problem. + * + * Why it "makes sense": If we pass a `@Nullable Foo`, then we should also pass an + * `Equivalence`. And there's no such thing because Equivalence doesn't + * permit nullable type arguments. + * + * Why there's no real problem: Every Equivalence can handle null. + * + * We could work around this by giving Wrapper 2 type parameters. In the terms of this method, + * that would be both the T parameter (from the class) and the S parameter (from this method). + * However, such a change would be source-incompatible. (Plus, there's no reason for the S + * parameter from the user's perspective, so it would be a wart.) + * + * We could probably also work around this by making Wrapper non-final and putting the + * implementation into a subclass with those 2 type parameters. But we like `final`, if only to + * deter users from using mocking frameworks to construct instances. (And could also complicate + * serialization, which is discussed more in the next paragraph.) + * + * We could probably also work around this by having Wrapper accept an instance of a new + * WrapperGuts class, which would then be the class that would declare the 2 type parameters. + * But that would break deserialization of previously serialized Wrapper instances. And while we + * specifically say not to rely on serialization across Guava versions, users sometimes do. So + * we'd rather not break them without a good enough reason. + * + * (We could work around the serialization problem by writing custom serialization code. But + * even that helps only the case of serializing with an old version and deserializing with a + * new, not vice versa -- unless we introduce WrapperGuts and the logic to handle it today, wait + * until "everyone" has picked up a version of Guava with that code, and *then* change to use + * WrapperGuts.) + * + * Anyway, a suppression isn't really a big deal. But I have tried to do some due diligence on + * avoiding it :) + */ + @SuppressWarnings("nullness") + Wrapper w = new Wrapper<>(this, reference); + return w; } /** @@ -172,17 +212,17 @@ public final Wrapper wrap(@NullableDecl S reference) { * * @since 10.0 */ - public static final class Wrapper implements Serializable { + public static final class Wrapper implements Serializable { private final Equivalence equivalence; - @NullableDecl private final T reference; + @ParametricNullness private final T reference; - private Wrapper(Equivalence equivalence, @NullableDecl T reference) { + private Wrapper(Equivalence equivalence, @ParametricNullness T reference) { this.equivalence = checkNotNull(equivalence); this.reference = reference; } /** Returns the (possibly null) reference wrapped by this instance. */ - @NullableDecl + @ParametricNullness public T get() { return reference; } @@ -193,7 +233,7 @@ public T get() { * equivalence. */ @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj == this) { return true; } @@ -243,10 +283,10 @@ public String toString() { * @since 10.0 */ @GwtCompatible(serializable = true) - public final Equivalence> pairwise() { + public final Equivalence> pairwise() { // Ideally, the returned equivalence would support Iterable. However, // the need for this is so rare that it's not worth making callers deal with the ugly wildcard. - return new PairwiseEquivalence(this); + return new PairwiseEquivalence<>(this); } /** @@ -255,27 +295,28 @@ public final Equivalence> pairwise() { * * @since 10.0 */ - public final Predicate equivalentTo(@NullableDecl T target) { + public final Predicate<@Nullable T> equivalentTo(@CheckForNull T target) { return new EquivalentToPredicate(this, target); } - private static final class EquivalentToPredicate implements Predicate, Serializable { + private static final class EquivalentToPredicate + implements Predicate<@Nullable T>, Serializable { private final Equivalence equivalence; - @NullableDecl private final T target; + @CheckForNull private final T target; - EquivalentToPredicate(Equivalence equivalence, @NullableDecl T target) { + EquivalentToPredicate(Equivalence equivalence, @CheckForNull T target) { this.equivalence = checkNotNull(equivalence); this.target = target; } @Override - public boolean apply(@NullableDecl T input) { + public boolean apply(@CheckForNull T input) { return equivalence.equivalent(input, target); } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (this == obj) { return true; } diff --git a/android/guava/src/com/google/common/base/ExtraObjectsMethodsForWeb.java b/android/guava/src/com/google/common/base/ExtraObjectsMethodsForWeb.java index 21cca2c109d6..677075522028 100644 --- a/android/guava/src/com/google/common/base/ExtraObjectsMethodsForWeb.java +++ b/android/guava/src/com/google/common/base/ExtraObjectsMethodsForWeb.java @@ -21,4 +21,5 @@ * version. */ @GwtCompatible(emulated = true) +@ElementTypesAreNonnullByDefault abstract class ExtraObjectsMethodsForWeb {} diff --git a/android/guava/src/com/google/common/base/FinalizablePhantomReference.java b/android/guava/src/com/google/common/base/FinalizablePhantomReference.java index f92057588a30..4f9399669569 100644 --- a/android/guava/src/com/google/common/base/FinalizablePhantomReference.java +++ b/android/guava/src/com/google/common/base/FinalizablePhantomReference.java @@ -17,6 +17,7 @@ import com.google.common.annotations.GwtIncompatible; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; +import javax.annotation.CheckForNull; /** * Phantom reference with a {@code finalizeReferent()} method which a background thread invokes @@ -29,6 +30,7 @@ * @since 2.0 */ @GwtIncompatible +@ElementTypesAreNonnullByDefault public abstract class FinalizablePhantomReference extends PhantomReference implements FinalizableReference { /** @@ -37,7 +39,7 @@ public abstract class FinalizablePhantomReference extends PhantomReference * @param referent to phantom reference * @param queue that should finalize the referent */ - protected FinalizablePhantomReference(T referent, FinalizableReferenceQueue queue) { + protected FinalizablePhantomReference(@CheckForNull T referent, FinalizableReferenceQueue queue) { super(referent, queue.queue); queue.cleanUp(); } diff --git a/android/guava/src/com/google/common/base/FinalizableReference.java b/android/guava/src/com/google/common/base/FinalizableReference.java index 848e7ee586d2..73753c9b3520 100644 --- a/android/guava/src/com/google/common/base/FinalizableReference.java +++ b/android/guava/src/com/google/common/base/FinalizableReference.java @@ -26,6 +26,7 @@ */ @DoNotMock("Use an instance of one of the Finalizable*Reference classes") @GwtIncompatible +@ElementTypesAreNonnullByDefault public interface FinalizableReference { /** * Invoked on a background thread after the referent has been garbage collected unless security diff --git a/android/guava/src/com/google/common/base/FinalizableReferenceQueue.java b/android/guava/src/com/google/common/base/FinalizableReferenceQueue.java index 40dfd462b81c..7447b8051d31 100644 --- a/android/guava/src/com/google/common/base/FinalizableReferenceQueue.java +++ b/android/guava/src/com/google/common/base/FinalizableReferenceQueue.java @@ -27,7 +27,7 @@ import java.net.URLClassLoader; import java.util.logging.Level; import java.util.logging.Logger; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * A reference queue with an associated background thread that dequeues references and invokes @@ -37,7 +37,7 @@ * finalized. If this object is garbage collected earlier, the backing thread will not invoke {@code * finalizeReferent()} on the remaining references. * - *

    As an example of how this is used, imagine you have a class {@code MyServer} that creates a a + *

    As an example of how this is used, imagine you have a class {@code MyServer} that creates a * {@link java.net.ServerSocket ServerSocket}, and you would like to ensure that the {@code * ServerSocket} is closed even if the {@code MyServer} object is garbage-collected without calling * its {@code close} method. You could use a finalizer to accomplish this, but that has a @@ -89,6 +89,7 @@ * @since 2.0 */ @GwtIncompatible +@ElementTypesAreNonnullByDefault public class FinalizableReferenceQueue implements Closeable { /* * The Finalizer thread keeps a phantom reference to this object. When the client (for example, a @@ -155,7 +156,7 @@ public class FinalizableReferenceQueue implements Closeable { public FinalizableReferenceQueue() { // We could start the finalizer lazily, but I'd rather it blow up early. queue = new ReferenceQueue<>(); - frqRef = new PhantomReference(this, queue); + frqRef = new PhantomReference<>(this, queue); boolean threadStarted = false; try { startFinalizer.invoke(null, FinalizableReference.class, queue, frqRef); @@ -228,7 +229,7 @@ interface FinalizerLoader { * * @throws SecurityException if we don't have the appropriate privileges */ - @NullableDecl + @CheckForNull Class loadFinalizer(); } @@ -242,7 +243,7 @@ static class SystemLoader implements FinalizerLoader { @VisibleForTesting static boolean disabled; @Override - @NullableDecl + @CheckForNull public Class loadFinalizer() { if (disabled) { return null; @@ -280,7 +281,7 @@ static class DecoupledLoader implements FinalizerLoader { + "issue, or move Guava to your system class path."; @Override - @NullableDecl + @CheckForNull public Class loadFinalizer() { try { /* diff --git a/android/guava/src/com/google/common/base/FinalizableSoftReference.java b/android/guava/src/com/google/common/base/FinalizableSoftReference.java index 45ecc656c0d4..c0e9b6bae041 100644 --- a/android/guava/src/com/google/common/base/FinalizableSoftReference.java +++ b/android/guava/src/com/google/common/base/FinalizableSoftReference.java @@ -17,6 +17,7 @@ import com.google.common.annotations.GwtIncompatible; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; +import javax.annotation.CheckForNull; /** * Soft reference with a {@code finalizeReferent()} method which a background thread invokes after @@ -27,6 +28,7 @@ * @since 2.0 */ @GwtIncompatible +@ElementTypesAreNonnullByDefault public abstract class FinalizableSoftReference extends SoftReference implements FinalizableReference { /** @@ -35,7 +37,7 @@ public abstract class FinalizableSoftReference extends SoftReference * @param referent to softly reference * @param queue that should finalize the referent */ - protected FinalizableSoftReference(T referent, FinalizableReferenceQueue queue) { + protected FinalizableSoftReference(@CheckForNull T referent, FinalizableReferenceQueue queue) { super(referent, queue.queue); queue.cleanUp(); } diff --git a/android/guava/src/com/google/common/base/FinalizableWeakReference.java b/android/guava/src/com/google/common/base/FinalizableWeakReference.java index fb3b09bb7dc4..9cca92ed5310 100644 --- a/android/guava/src/com/google/common/base/FinalizableWeakReference.java +++ b/android/guava/src/com/google/common/base/FinalizableWeakReference.java @@ -17,6 +17,7 @@ import com.google.common.annotations.GwtIncompatible; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; +import javax.annotation.CheckForNull; /** * Weak reference with a {@code finalizeReferent()} method which a background thread invokes after @@ -27,6 +28,7 @@ * @since 2.0 */ @GwtIncompatible +@ElementTypesAreNonnullByDefault public abstract class FinalizableWeakReference extends WeakReference implements FinalizableReference { /** @@ -35,7 +37,7 @@ public abstract class FinalizableWeakReference extends WeakReference * @param referent to weakly reference * @param queue that should finalize the referent */ - protected FinalizableWeakReference(T referent, FinalizableReferenceQueue queue) { + protected FinalizableWeakReference(@CheckForNull T referent, FinalizableReferenceQueue queue) { super(referent, queue.queue); queue.cleanUp(); } diff --git a/android/guava/src/com/google/common/base/Function.java b/android/guava/src/com/google/common/base/Function.java index 05831867fef8..7d633af21c61 100644 --- a/android/guava/src/com/google/common/base/Function.java +++ b/android/guava/src/com/google/common/base/Function.java @@ -16,7 +16,8 @@ import com.google.common.annotations.GwtCompatible; import com.google.errorprone.annotations.CanIgnoreReturnValue; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Determines an output value based on an input value; a pre-Java-8 version of {@link @@ -44,7 +45,8 @@ * @since 2.0 */ @GwtCompatible -public interface Function { +@ElementTypesAreNonnullByDefault +public interface Function { /** * Returns the result of applying this function to {@code input}. This method is generally * expected, but not absolutely required, to have the following properties: @@ -60,8 +62,8 @@ public interface Function { * arguments */ @CanIgnoreReturnValue // TODO(kevinb): remove this - @NullableDecl - T apply(@NullableDecl F input); + @ParametricNullness + T apply(@ParametricNullness F input); /** * May return {@code true} if {@code object} is a {@code Function} that behaves identically @@ -75,5 +77,5 @@ public interface Function { * disappear. It is best not to depend on it. */ @Override - boolean equals(@NullableDecl Object object); + boolean equals(@CheckForNull Object object); } diff --git a/android/guava/src/com/google/common/base/FunctionalEquivalence.java b/android/guava/src/com/google/common/base/FunctionalEquivalence.java index 17dd40078124..4383f4f36c1a 100644 --- a/android/guava/src/com/google/common/base/FunctionalEquivalence.java +++ b/android/guava/src/com/google/common/base/FunctionalEquivalence.java @@ -19,7 +19,8 @@ import com.google.common.annotations.Beta; import com.google.common.annotations.GwtCompatible; import java.io.Serializable; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Equivalence applied on functional result. @@ -29,14 +30,16 @@ */ @Beta @GwtCompatible +@ElementTypesAreNonnullByDefault final class FunctionalEquivalence extends Equivalence implements Serializable { private static final long serialVersionUID = 0; - private final Function function; + private final Function function; private final Equivalence resultEquivalence; - FunctionalEquivalence(Function function, Equivalence resultEquivalence) { + FunctionalEquivalence( + Function function, Equivalence resultEquivalence) { this.function = checkNotNull(function); this.resultEquivalence = checkNotNull(resultEquivalence); } @@ -52,7 +55,7 @@ protected int doHash(F a) { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj == this) { return true; } diff --git a/android/guava/src/com/google/common/base/Functions.java b/android/guava/src/com/google/common/base/Functions.java index 805f15c73727..78785047eb82 100644 --- a/android/guava/src/com/google/common/base/Functions.java +++ b/android/guava/src/com/google/common/base/Functions.java @@ -14,13 +14,15 @@ package com.google.common.base; +import static com.google.common.base.NullnessCasts.uncheckedCastNullableTToT; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.annotations.GwtCompatible; import java.io.Serializable; import java.util.Map; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Static utility methods pertaining to {@code com.google.common.base.Function} instances; see that @@ -36,6 +38,7 @@ * @since 2.0 */ @GwtCompatible +@ElementTypesAreNonnullByDefault public final class Functions { private Functions() {} @@ -79,17 +82,17 @@ public String toString() { /** Returns the identity function. */ // implementation is "fully variant"; E has become a "pass-through" type @SuppressWarnings("unchecked") - public static Function identity() { + public static Function identity() { return (Function) IdentityFunction.INSTANCE; } // enum singleton pattern - private enum IdentityFunction implements Function { + private enum IdentityFunction implements Function<@Nullable Object, @Nullable Object> { INSTANCE; @Override - @NullableDecl - public Object apply(@NullableDecl Object o) { + @CheckForNull + public Object apply(@CheckForNull Object o) { return o; } @@ -112,7 +115,8 @@ public String toString() { * key (instead of an exception being thrown), you can use the method reference {@code map::get} * instead. */ - public static Function forMap(Map map) { + public static Function forMap( + Map map) { return new FunctionForMapNoDefault<>(map); } @@ -129,12 +133,14 @@ public static Function forMap(Map map) { * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code * defaultValue} otherwise */ - public static Function forMap( - Map map, @NullableDecl V defaultValue) { + public static Function forMap( + Map map, @ParametricNullness V defaultValue) { return new ForMapWithDefault<>(map, defaultValue); } - private static class FunctionForMapNoDefault implements Function, Serializable { + private static class FunctionForMapNoDefault< + K extends @Nullable Object, V extends @Nullable Object> + implements Function, Serializable { final Map map; FunctionForMapNoDefault(Map map) { @@ -142,14 +148,16 @@ private static class FunctionForMapNoDefault implements Function, Se } @Override - public V apply(@NullableDecl K key) { + @ParametricNullness + public V apply(@ParametricNullness K key) { V result = map.get(key); checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key); - return result; + // The unchecked cast is safe because of the containsKey check. + return uncheckedCastNullableTToT(result); } @Override - public boolean equals(@NullableDecl Object o) { + public boolean equals(@CheckForNull Object o) { if (o instanceof FunctionForMapNoDefault) { FunctionForMapNoDefault that = (FunctionForMapNoDefault) o; return map.equals(that.map); @@ -170,23 +178,28 @@ public String toString() { private static final long serialVersionUID = 0; } - private static class ForMapWithDefault implements Function, Serializable { + private static class ForMapWithDefault + implements Function, Serializable { final Map map; - @NullableDecl final V defaultValue; + @ParametricNullness final V defaultValue; - ForMapWithDefault(Map map, @NullableDecl V defaultValue) { + ForMapWithDefault(Map map, @ParametricNullness V defaultValue) { this.map = checkNotNull(map); this.defaultValue = defaultValue; } @Override - public V apply(@NullableDecl K key) { + @ParametricNullness + public V apply(@ParametricNullness K key) { V result = map.get(key); - return (result != null || map.containsKey(key)) ? result : defaultValue; + // The unchecked cast is safe because of the containsKey check. + return (result != null || map.containsKey(key)) + ? uncheckedCastNullableTToT(result) + : defaultValue; } @Override - public boolean equals(@NullableDecl Object o) { + public boolean equals(@CheckForNull Object o) { if (o instanceof ForMapWithDefault) { ForMapWithDefault that = (ForMapWithDefault) o; return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue); @@ -220,11 +233,14 @@ public String toString() { * @return the composition of {@code f} and {@code g} * @see function composition */ - public static Function compose(Function g, Function f) { + public static + Function compose(Function g, Function f) { return new FunctionComposition<>(g, f); } - private static class FunctionComposition implements Function, Serializable { + private static class FunctionComposition< + A extends @Nullable Object, B extends @Nullable Object, C extends @Nullable Object> + implements Function, Serializable { private final Function g; private final Function f; @@ -234,12 +250,13 @@ public FunctionComposition(Function g, Function f) { } @Override - public C apply(@NullableDecl A a) { + @ParametricNullness + public C apply(@ParametricNullness A a) { return g.apply(f.apply(a)); } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof FunctionComposition) { FunctionComposition that = (FunctionComposition) obj; return f.equals(that.f) && g.equals(that.g); @@ -269,12 +286,14 @@ public String toString() { * *

    Java 8 users: use the method reference {@code predicate::test} instead. */ - public static Function forPredicate(Predicate predicate) { - return new PredicateFunction(predicate); + public static Function forPredicate( + Predicate predicate) { + return new PredicateFunction<>(predicate); } /** @see Functions#forPredicate */ - private static class PredicateFunction implements Function, Serializable { + private static class PredicateFunction + implements Function, Serializable { private final Predicate predicate; private PredicateFunction(Predicate predicate) { @@ -282,12 +301,12 @@ private PredicateFunction(Predicate predicate) { } @Override - public Boolean apply(@NullableDecl T t) { + public Boolean apply(@ParametricNullness T t) { return predicate.apply(t); } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof PredicateFunction) { PredicateFunction that = (PredicateFunction) obj; return predicate.equals(that.predicate); @@ -316,24 +335,27 @@ public String toString() { * @param value the constant value for the function to return * @return a function that always returns {@code value} */ - public static Function constant(@NullableDecl E value) { - return new ConstantFunction(value); + public static Function<@Nullable Object, E> constant( + @ParametricNullness E value) { + return new ConstantFunction<>(value); } - private static class ConstantFunction implements Function, Serializable { - @NullableDecl private final E value; + private static class ConstantFunction + implements Function<@Nullable Object, E>, Serializable { + @ParametricNullness private final E value; - public ConstantFunction(@NullableDecl E value) { + public ConstantFunction(@ParametricNullness E value) { this.value = value; } @Override - public E apply(@NullableDecl Object from) { + @ParametricNullness + public E apply(@CheckForNull Object from) { return value; } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof ConstantFunction) { ConstantFunction that = (ConstantFunction) obj; return Objects.equal(value, that.value); @@ -361,12 +383,14 @@ public String toString() { * * @since 10.0 */ - public static Function forSupplier(Supplier supplier) { - return new SupplierFunction(supplier); + public static Function forSupplier( + Supplier supplier) { + return new SupplierFunction<>(supplier); } /** @see Functions#forSupplier */ - private static class SupplierFunction implements Function, Serializable { + private static class SupplierFunction + implements Function, Serializable { private final Supplier supplier; @@ -375,14 +399,15 @@ private SupplierFunction(Supplier supplier) { } @Override - public T apply(@NullableDecl Object input) { + @ParametricNullness + public T apply(@ParametricNullness F input) { return supplier.get(); } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof SupplierFunction) { - SupplierFunction that = (SupplierFunction) obj; + SupplierFunction that = (SupplierFunction) obj; return this.supplier.equals(that.supplier); } return false; diff --git a/android/guava/src/com/google/common/base/Java8Compatibility.java b/android/guava/src/com/google/common/base/Java8Compatibility.java new file mode 100644 index 000000000000..edc8b73bdd10 --- /dev/null +++ b/android/guava/src/com/google/common/base/Java8Compatibility.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.base; + +import com.google.common.annotations.GwtIncompatible; +import java.nio.Buffer; + +/** + * Wrappers around {@link Buffer} methods that are covariantly overridden in Java 9+. See + * https://github.com/google/guava/issues/3990 + */ +@GwtIncompatible +@ElementTypesAreNonnullByDefault +final class Java8Compatibility { + static void clear(Buffer b) { + b.clear(); + } + + static void flip(Buffer b) { + b.flip(); + } + + static void limit(Buffer b, int limit) { + b.limit(limit); + } + + static void position(Buffer b, int position) { + b.position(position); + } + + private Java8Compatibility() {} +} diff --git a/android/guava/src/com/google/common/base/Java8Usage.java b/android/guava/src/com/google/common/base/Java8Usage.java deleted file mode 100755 index 78130cf676d9..000000000000 --- a/android/guava/src/com/google/common/base/Java8Usage.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2020 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - -import com.google.errorprone.annotations.CanIgnoreReturnValue; - -/** - * A class that uses a couple Java 8 features but doesn't really do anything. This lets us attempt - * to load it and log a warning if that fails, giving users advance notice of our dropping Java 8 - * support. - */ -/* - * This class should be annotated @GwtCompatible. But if we annotate it @GwtCompatible, then we need - * to build GwtCompatible.java (-source 7 -target 7 in the Android flavor) before we build - * Java8Usage.java (-source 8 target 8, which we already need to build before the rest of - * common.base). We could configure Maven to do that, but it's easier to just skip the annotation. - */ -final class Java8Usage { - @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE) - @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) - private @interface SomeTypeAnnotation {} - - @CanIgnoreReturnValue - static @SomeTypeAnnotation String performCheck() { - Runnable r = () -> {}; - r.run(); - return ""; - } - - private Java8Usage() {} -} diff --git a/android/guava/src/com/google/common/base/JdkPattern.java b/android/guava/src/com/google/common/base/JdkPattern.java index f7791dba6e95..4788398b7c20 100644 --- a/android/guava/src/com/google/common/base/JdkPattern.java +++ b/android/guava/src/com/google/common/base/JdkPattern.java @@ -20,6 +20,7 @@ import java.util.regex.Pattern; /** A regex pattern implementation which is backed by the {@link Pattern}. */ +@ElementTypesAreNonnullByDefault @GwtIncompatible final class JdkPattern extends CommonPattern implements Serializable { private final Pattern pattern; diff --git a/android/guava/src/com/google/common/base/Joiner.java b/android/guava/src/com/google/common/base/Joiner.java index f74f02feba0a..8b29f68f8ad1 100644 --- a/android/guava/src/com/google/common/base/Joiner.java +++ b/android/guava/src/com/google/common/base/Joiner.java @@ -15,6 +15,7 @@ package com.google.common.base; import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.requireNonNull; import com.google.common.annotations.Beta; import com.google.common.annotations.GwtCompatible; @@ -25,7 +26,8 @@ import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * An object which joins pieces of text (specified as an array, {@link Iterable}, varargs or even a @@ -63,6 +65,7 @@ * @since 2.0 */ @GwtCompatible +@ElementTypesAreNonnullByDefault public class Joiner { /** Returns a joiner which automatically places {@code separator} between consecutive elements. */ public static Joiner on(String separator) { @@ -84,12 +87,19 @@ private Joiner(Joiner prototype) { this.separator = prototype.separator; } + /* + * In this file, we use instead of to work around a Kotlin bug + * (see b/189937072 until we file a bug against Kotlin itself). (The two should be equivalent, so + * we normally prefer the shorter one.) + */ + /** * Appends the string representation of each of {@code parts}, using the previously configured * separator between each, to {@code appendable}. */ @CanIgnoreReturnValue - public A appendTo(A appendable, Iterable parts) throws IOException { + public A appendTo(A appendable, Iterable parts) + throws IOException { return appendTo(appendable, parts.iterator()); } @@ -100,7 +110,8 @@ public A appendTo(A appendable, Iterable parts) throws * @since 11.0 */ @CanIgnoreReturnValue - public A appendTo(A appendable, Iterator parts) throws IOException { + public A appendTo(A appendable, Iterator parts) + throws IOException { checkNotNull(appendable); if (parts.hasNext()) { appendable.append(toString(parts.next())); @@ -117,14 +128,18 @@ public A appendTo(A appendable, Iterator parts) throws * separator between each, to {@code appendable}. */ @CanIgnoreReturnValue - public final A appendTo(A appendable, Object[] parts) throws IOException { + public final A appendTo(A appendable, @Nullable Object[] parts) + throws IOException { return appendTo(appendable, Arrays.asList(parts)); } /** Appends to {@code appendable} the string representation of each of the remaining arguments. */ @CanIgnoreReturnValue public final A appendTo( - A appendable, @NullableDecl Object first, @NullableDecl Object second, Object... rest) + A appendable, + @CheckForNull Object first, + @CheckForNull Object second, + @Nullable Object... rest) throws IOException { return appendTo(appendable, iterable(first, second, rest)); } @@ -135,7 +150,8 @@ public final A appendTo( * Iterable)}, except that it does not throw {@link IOException}. */ @CanIgnoreReturnValue - public final StringBuilder appendTo(StringBuilder builder, Iterable parts) { + public final StringBuilder appendTo( + StringBuilder builder, Iterable parts) { return appendTo(builder, parts.iterator()); } @@ -147,7 +163,8 @@ public final StringBuilder appendTo(StringBuilder builder, Iterable parts) { * @since 11.0 */ @CanIgnoreReturnValue - public final StringBuilder appendTo(StringBuilder builder, Iterator parts) { + public final StringBuilder appendTo( + StringBuilder builder, Iterator parts) { try { appendTo((Appendable) builder, parts); } catch (IOException impossible) { @@ -162,7 +179,7 @@ public final StringBuilder appendTo(StringBuilder builder, Iterator parts) { * Iterable)}, except that it does not throw {@link IOException}. */ @CanIgnoreReturnValue - public final StringBuilder appendTo(StringBuilder builder, Object[] parts) { + public final StringBuilder appendTo(StringBuilder builder, @Nullable Object[] parts) { return appendTo(builder, Arrays.asList(parts)); } @@ -174,9 +191,9 @@ public final StringBuilder appendTo(StringBuilder builder, Object[] parts) { @CanIgnoreReturnValue public final StringBuilder appendTo( StringBuilder builder, - @NullableDecl Object first, - @NullableDecl Object second, - Object... rest) { + @CheckForNull Object first, + @CheckForNull Object second, + @Nullable Object... rest) { return appendTo(builder, iterable(first, second, rest)); } @@ -184,7 +201,7 @@ public final StringBuilder appendTo( * Returns a string containing the string representation of each of {@code parts}, using the * previously configured separator between each. */ - public final String join(Iterable parts) { + public final String join(Iterable parts) { return join(parts.iterator()); } @@ -194,7 +211,7 @@ public final String join(Iterable parts) { * * @since 11.0 */ - public final String join(Iterator parts) { + public final String join(Iterator parts) { return appendTo(new StringBuilder(), parts).toString(); } @@ -202,7 +219,7 @@ public final String join(Iterator parts) { * Returns a string containing the string representation of each of {@code parts}, using the * previously configured separator between each. */ - public final String join(Object[] parts) { + public final String join(@Nullable Object[] parts) { return join(Arrays.asList(parts)); } @@ -211,7 +228,7 @@ public final String join(Object[] parts) { * configured separator between each. */ public final String join( - @NullableDecl Object first, @NullableDecl Object second, Object... rest) { + @CheckForNull Object first, @CheckForNull Object second, @Nullable Object... rest) { return join(iterable(first, second, rest)); } @@ -219,11 +236,11 @@ public final String join( * Returns a joiner with the same behavior as this one, except automatically substituting {@code * nullText} for any provided null elements. */ - public Joiner useForNull(final String nullText) { + public Joiner useForNull(String nullText) { checkNotNull(nullText); return new Joiner(this) { @Override - CharSequence toString(@NullableDecl Object part) { + CharSequence toString(@CheckForNull Object part) { return (part == null) ? nullText : Joiner.this.toString(part); } @@ -246,7 +263,8 @@ public Joiner skipNulls() { public Joiner skipNulls() { return new Joiner(this) { @Override - public A appendTo(A appendable, Iterator parts) throws IOException { + public A appendTo( + A appendable, Iterator parts) throws IOException { checkNotNull(appendable, "appendable"); checkNotNull(parts, "parts"); while (parts.hasNext()) { @@ -452,21 +470,39 @@ public MapJoiner useForNull(String nullText) { } } - CharSequence toString(Object part) { - checkNotNull(part); // checkNotNull for GWT (do not optimize). + CharSequence toString(@CheckForNull Object part) { + /* + * requireNonNull is not safe: Joiner.on(...).join(somethingThatContainsNull) will indeed throw. + * However, Joiner.on(...).useForNull(...).join(somethingThatContainsNull) *is* safe -- because + * it returns a subclass of Joiner that overrides this method to tolerate null inputs. + * + * Unfortunately, we don't distinguish between these two cases in our public API: Joiner.on(...) + * and Joiner.on(...).useForNull(...) both declare the same return type: plain Joiner. To ensure + * that users *can* pass null arguments to Joiner, we annotate it as if it always tolerates null + * inputs, rather than as if it never tolerates them. + * + * We rely on checkers to implement special cases to catch dangerous calls to join(), etc. based + * on what they know about the particular Joiner instances the calls are performed on. + * + * (In addition to useForNull, we also offer skipNulls. It, too, tolerates null inputs, but its + * tolerance is implemented differently: Its implementation avoids calling this toString(Object) + * method in the first place.) + */ + requireNonNull(part); return (part instanceof CharSequence) ? (CharSequence) part : part.toString(); } - private static Iterable iterable( - final Object first, final Object second, final Object[] rest) { + private static Iterable<@Nullable Object> iterable( + @CheckForNull Object first, @CheckForNull Object second, @Nullable Object[] rest) { checkNotNull(rest); - return new AbstractList() { + return new AbstractList<@Nullable Object>() { @Override public int size() { return rest.length + 2; } @Override + @CheckForNull public Object get(int index) { switch (index) { case 0: diff --git a/android/guava/src/com/google/common/base/MoreObjects.java b/android/guava/src/com/google/common/base/MoreObjects.java index a56b2a69def0..da976242479b 100644 --- a/android/guava/src/com/google/common/base/MoreObjects.java +++ b/android/guava/src/com/google/common/base/MoreObjects.java @@ -18,8 +18,11 @@ import com.google.common.annotations.GwtCompatible; import com.google.errorprone.annotations.CanIgnoreReturnValue; +import java.lang.reflect.Array; import java.util.Arrays; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import java.util.Collection; +import java.util.Map; +import javax.annotation.CheckForNull; /** * Helper functions that operate on any {@code Object}, and are not already provided in {@link @@ -33,6 +36,7 @@ * @since 18.0 (since 2.0 as {@code Objects}) */ @GwtCompatible +@ElementTypesAreNonnullByDefault public final class MoreObjects { /** * Returns the first of two given parameters that is not {@code null}, if either is, or otherwise @@ -54,7 +58,24 @@ public final class MoreObjects { * @throws NullPointerException if both {@code first} and {@code second} are null * @since 18.0 (since 3.0 as {@code Objects.firstNonNull()}). */ - public static T firstNonNull(@NullableDecl T first, @NullableDecl T second) { + /* + * We annotate firstNonNull in a way that protects against NullPointerException at the cost of + * forbidding some reasonable calls. + * + * The more permissive signature would be to accept (@CheckForNull T first, @CheckForNull T + * second), since it's OK for `second` to be null as long as `first` is not also null. But we + * expect for that flexibility to be useful relatively rarely: The more common use case is to + * supply a clearly non-null default, like `firstNonNull(someString, "")`. And users who really + * know that `first` is guaranteed non-null when `second` is null can write the logic out + * longhand, including a requireNonNull call, which calls attention to the fact that the static + * analyzer can't prove that the operation is safe. + * + * This matches the signature we currently have for requireNonNullElse in our own checker. (And + * that in turn matches that method's signature under the Checker Framework.) As always, we could + * consider the more flexible signature if we judge it worth the risks. If we do, we would likely + * update both methods so that they continue to match. + */ + public static T firstNonNull(@CheckForNull T first, T second) { if (first != null) { return first; } @@ -145,6 +166,7 @@ public static final class ToStringHelper { private final ValueHolder holderHead = new ValueHolder(); private ValueHolder holderTail = holderHead; private boolean omitNullValues = false; + private boolean omitEmptyValues = false; /** Use {@link MoreObjects#toStringHelper(Object)} to create an instance. */ private ToStringHelper(String className) { @@ -170,7 +192,7 @@ public ToStringHelper omitNullValues() { * called, in which case this name/value pair will not be added. */ @CanIgnoreReturnValue - public ToStringHelper add(String name, @NullableDecl Object value) { + public ToStringHelper add(String name, @CheckForNull Object value) { return addHolder(name, value); } @@ -181,7 +203,7 @@ public ToStringHelper add(String name, @NullableDecl Object value) { */ @CanIgnoreReturnValue public ToStringHelper add(String name, boolean value) { - return addHolder(name, String.valueOf(value)); + return addUnconditionalHolder(name, String.valueOf(value)); } /** @@ -191,7 +213,7 @@ public ToStringHelper add(String name, boolean value) { */ @CanIgnoreReturnValue public ToStringHelper add(String name, char value) { - return addHolder(name, String.valueOf(value)); + return addUnconditionalHolder(name, String.valueOf(value)); } /** @@ -201,7 +223,7 @@ public ToStringHelper add(String name, char value) { */ @CanIgnoreReturnValue public ToStringHelper add(String name, double value) { - return addHolder(name, String.valueOf(value)); + return addUnconditionalHolder(name, String.valueOf(value)); } /** @@ -211,7 +233,7 @@ public ToStringHelper add(String name, double value) { */ @CanIgnoreReturnValue public ToStringHelper add(String name, float value) { - return addHolder(name, String.valueOf(value)); + return addUnconditionalHolder(name, String.valueOf(value)); } /** @@ -221,7 +243,7 @@ public ToStringHelper add(String name, float value) { */ @CanIgnoreReturnValue public ToStringHelper add(String name, int value) { - return addHolder(name, String.valueOf(value)); + return addUnconditionalHolder(name, String.valueOf(value)); } /** @@ -231,7 +253,7 @@ public ToStringHelper add(String name, int value) { */ @CanIgnoreReturnValue public ToStringHelper add(String name, long value) { - return addHolder(name, String.valueOf(value)); + return addUnconditionalHolder(name, String.valueOf(value)); } /** @@ -241,7 +263,7 @@ public ToStringHelper add(String name, long value) { * readable name. */ @CanIgnoreReturnValue - public ToStringHelper addValue(@NullableDecl Object value) { + public ToStringHelper addValue(@CheckForNull Object value) { return addHolder(value); } @@ -255,7 +277,7 @@ public ToStringHelper addValue(@NullableDecl Object value) { */ @CanIgnoreReturnValue public ToStringHelper addValue(boolean value) { - return addHolder(String.valueOf(value)); + return addUnconditionalHolder(String.valueOf(value)); } /** @@ -268,7 +290,7 @@ public ToStringHelper addValue(boolean value) { */ @CanIgnoreReturnValue public ToStringHelper addValue(char value) { - return addHolder(String.valueOf(value)); + return addUnconditionalHolder(String.valueOf(value)); } /** @@ -281,7 +303,7 @@ public ToStringHelper addValue(char value) { */ @CanIgnoreReturnValue public ToStringHelper addValue(double value) { - return addHolder(String.valueOf(value)); + return addUnconditionalHolder(String.valueOf(value)); } /** @@ -294,7 +316,7 @@ public ToStringHelper addValue(double value) { */ @CanIgnoreReturnValue public ToStringHelper addValue(float value) { - return addHolder(String.valueOf(value)); + return addUnconditionalHolder(String.valueOf(value)); } /** @@ -307,7 +329,7 @@ public ToStringHelper addValue(float value) { */ @CanIgnoreReturnValue public ToStringHelper addValue(int value) { - return addHolder(String.valueOf(value)); + return addUnconditionalHolder(String.valueOf(value)); } /** @@ -320,7 +342,23 @@ public ToStringHelper addValue(int value) { */ @CanIgnoreReturnValue public ToStringHelper addValue(long value) { - return addHolder(String.valueOf(value)); + return addUnconditionalHolder(String.valueOf(value)); + } + + private static boolean isEmpty(Object value) { + // Put types estimated to be most frequent first. + if (value instanceof CharSequence) { + return ((CharSequence) value).length() == 0; + } else if (value instanceof Collection) { + return ((Collection) value).isEmpty(); + } else if (value instanceof Map) { + return ((Map) value).isEmpty(); + } else if (value instanceof Optional) { + return !((Optional) value).isPresent(); + } else if (value.getClass().isArray()) { + return Array.getLength(value) == 0; + } + return false; } /** @@ -335,13 +373,17 @@ public ToStringHelper addValue(long value) { public String toString() { // create a copy to keep it consistent in case value changes boolean omitNullValuesSnapshot = omitNullValues; + boolean omitEmptyValuesSnapshot = omitEmptyValues; String nextSeparator = ""; StringBuilder builder = new StringBuilder(32).append(className).append('{'); for (ValueHolder valueHolder = holderHead.next; valueHolder != null; valueHolder = valueHolder.next) { Object value = valueHolder.value; - if (!omitNullValuesSnapshot || value != null) { + if (valueHolder instanceof UnconditionalValueHolder + || (value == null + ? !omitNullValuesSnapshot + : (!omitEmptyValuesSnapshot || !isEmpty(value)))) { builder.append(nextSeparator); nextSeparator = ", "; @@ -366,24 +408,51 @@ private ValueHolder addHolder() { return valueHolder; } - private ToStringHelper addHolder(@NullableDecl Object value) { + private ToStringHelper addHolder(@CheckForNull Object value) { ValueHolder valueHolder = addHolder(); valueHolder.value = value; return this; } - private ToStringHelper addHolder(String name, @NullableDecl Object value) { + private ToStringHelper addHolder(String name, @CheckForNull Object value) { ValueHolder valueHolder = addHolder(); valueHolder.value = value; valueHolder.name = checkNotNull(name); return this; } - private static final class ValueHolder { - @NullableDecl String name; - @NullableDecl Object value; - @NullableDecl ValueHolder next; + private UnconditionalValueHolder addUnconditionalHolder() { + UnconditionalValueHolder valueHolder = new UnconditionalValueHolder(); + holderTail = holderTail.next = valueHolder; + return valueHolder; + } + + private ToStringHelper addUnconditionalHolder(Object value) { + UnconditionalValueHolder valueHolder = addUnconditionalHolder(); + valueHolder.value = value; + return this; + } + + private ToStringHelper addUnconditionalHolder(String name, Object value) { + UnconditionalValueHolder valueHolder = addUnconditionalHolder(); + valueHolder.value = value; + valueHolder.name = checkNotNull(name); + return this; + } + + // Holder object for values that might be null and/or empty. + private static class ValueHolder { + @CheckForNull String name; + @CheckForNull Object value; + @CheckForNull ValueHolder next; } + + /** + * Holder object for values that cannot be null or empty (will be printed unconditionally). This + * helps to shortcut most calls to isEmpty(), which is important because the check for emptiness + * is relatively expensive. Use a subtype so this also doesn't need any extra storage. + */ + private static final class UnconditionalValueHolder extends ValueHolder {} } private MoreObjects() {} diff --git a/android/guava/src/com/google/common/base/NullnessCasts.java b/android/guava/src/com/google/common/base/NullnessCasts.java new file mode 100644 index 000000000000..1ada6bf26148 --- /dev/null +++ b/android/guava/src/com/google/common/base/NullnessCasts.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.base; + +import com.google.common.annotations.GwtCompatible; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** A utility method to perform unchecked casts to suppress errors produced by nullness analyses. */ +@GwtCompatible +@ElementTypesAreNonnullByDefault +final class NullnessCasts { + /** + * Accepts a {@code @Nullable T} and returns a plain {@code T}, without performing any check that + * that conversion is safe. + * + *

    This method is intended to help with usages of type parameters that have {@linkplain + * ParametricNullness parametric nullness}. If a type parameter instead ranges over only non-null + * types (or if the type is a non-variable type, like {@code String}), then code should almost + * never use this method, preferring instead to call {@code requireNonNull} so as to benefit from + * its runtime check. + * + *

    An example use case for this method is in implementing an {@code Iterator} whose {@code + * next} field is lazily initialized. The type of that field would be {@code @Nullable T}, and the + * code would be responsible for populating a "real" {@code T} (which might still be the value + * {@code null}!) before returning it to callers. Depending on how the code is structured, a + * nullness analysis might not understand that the field has been populated. To avoid that problem + * without having to add {@code @SuppressWarnings}, the code can call this method. + * + *

    Why not just add {@code SuppressWarnings}? The problem is that this method is + * typically useful for {@code return} statements. That leaves the code with two options: Either + * add the suppression to the whole method (which turns off checking for a large section of code), + * or extract a variable, and put the suppression on that. However, a local variable typically + * doesn't work: Because nullness analyses typically infer the nullness of local variables, + * there's no way to assign a {@code @Nullable T} to a field {@code T foo;} and instruct the + * analysis that that means "plain {@code T}" rather than the inferred type {@code @Nullable T}. + * (Even if supported added {@code @NonNull}, that would not help, since the problem case + * addressed by this method is the case in which {@code T} has parametric nullness -- and thus its + * value may be legitimately {@code null}.) + */ + @ParametricNullness + @SuppressWarnings("nullness") + static T uncheckedCastNullableTToT(@CheckForNull T t) { + return t; + } + + private NullnessCasts() {} +} diff --git a/android/guava/src/com/google/common/base/Objects.java b/android/guava/src/com/google/common/base/Objects.java index 1a409a68df02..bd6b0d94c5f0 100644 --- a/android/guava/src/com/google/common/base/Objects.java +++ b/android/guava/src/com/google/common/base/Objects.java @@ -16,7 +16,8 @@ import com.google.common.annotations.GwtCompatible; import java.util.Arrays; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Helper functions that can operate on any {@code Object}. @@ -29,6 +30,7 @@ * @since 2.0 */ @GwtCompatible +@ElementTypesAreNonnullByDefault public final class Objects extends ExtraObjectsMethodsForWeb { private Objects() {} @@ -48,7 +50,7 @@ private Objects() {} *

    Note for Java 7 and later: This method should be treated as deprecated; use {@link * java.util.Objects#equals} instead. */ - public static boolean equal(@NullableDecl Object a, @NullableDecl Object b) { + public static boolean equal(@CheckForNull Object a, @CheckForNull Object b) { return a == b || (a != null && a.equals(b)); } @@ -73,7 +75,7 @@ public static boolean equal(@NullableDecl Object a, @NullableDecl Object b) { *

    Note for Java 7 and later: This method should be treated as deprecated; use {@link * java.util.Objects#hash} instead. */ - public static int hashCode(@NullableDecl Object... objects) { + public static int hashCode(@CheckForNull @Nullable Object... objects) { return Arrays.hashCode(objects); } } diff --git a/android/guava/src/com/google/common/base/Optional.java b/android/guava/src/com/google/common/base/Optional.java index 611ba54942b0..a7a0b3d72038 100644 --- a/android/guava/src/com/google/common/base/Optional.java +++ b/android/guava/src/com/google/common/base/Optional.java @@ -22,7 +22,7 @@ import java.io.Serializable; import java.util.Iterator; import java.util.Set; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * An immutable object that may contain a non-null reference to another object. Each instance of @@ -82,6 +82,7 @@ */ @DoNotMock("Use Optional.of(value) or Optional.absent()") @GwtCompatible(serializable = true) +@ElementTypesAreNonnullByDefault public abstract class Optional implements Serializable { /** * Returns an {@code Optional} instance with no contained reference. @@ -112,7 +113,7 @@ public static Optional of(T reference) { *

    Comparison to {@code java.util.Optional}: this method is equivalent to Java 8's * {@code Optional.ofNullable}. */ - public static Optional fromNullable(@NullableDecl T nullableReference) { + public static Optional fromNullable(@CheckForNull T nullableReference) { return (nullableReference == null) ? Optional.absent() : new Present(nullableReference); } @@ -206,7 +207,7 @@ public static Optional fromNullable(@NullableDecl T nullableReference) { *

    Comparison to {@code java.util.Optional}: this method is equivalent to Java 8's * {@code Optional.orElse(null)}. */ - @NullableDecl + @CheckForNull public abstract T orNull(); /** @@ -255,7 +256,7 @@ public static Optional fromNullable(@NullableDecl T nullableReference) { *

    Comparison to {@code java.util.Optional}: no differences. */ @Override - public abstract boolean equals(@NullableDecl Object object); + public abstract boolean equals(@CheckForNull Object object); /** * Returns a hash code for this instance. @@ -300,6 +301,7 @@ public Iterator iterator() { checkNotNull(optionals.iterator()); @Override + @CheckForNull protected T computeNext() { while (iterator.hasNext()) { Optional optional = iterator.next(); diff --git a/android/guava/src/com/google/common/base/PairwiseEquivalence.java b/android/guava/src/com/google/common/base/PairwiseEquivalence.java index cb7d784f016c..74be27fd7c6f 100644 --- a/android/guava/src/com/google/common/base/PairwiseEquivalence.java +++ b/android/guava/src/com/google/common/base/PairwiseEquivalence.java @@ -17,14 +17,16 @@ import com.google.common.annotations.GwtCompatible; import java.io.Serializable; import java.util.Iterator; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; @GwtCompatible(serializable = true) -final class PairwiseEquivalence extends Equivalence> implements Serializable { +@ElementTypesAreNonnullByDefault +final class PairwiseEquivalence extends Equivalence> + implements Serializable { + final Equivalence elementEquivalence; - final Equivalence elementEquivalence; - - PairwiseEquivalence(Equivalence elementEquivalence) { + PairwiseEquivalence(Equivalence elementEquivalence) { this.elementEquivalence = Preconditions.checkNotNull(elementEquivalence); } @@ -52,9 +54,9 @@ protected int doHash(Iterable iterable) { } @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { if (object instanceof PairwiseEquivalence) { - PairwiseEquivalence that = (PairwiseEquivalence) object; + PairwiseEquivalence that = (PairwiseEquivalence) object; return this.elementEquivalence.equals(that.elementEquivalence); } diff --git a/android/guava/src/com/google/common/base/ParametricNullness.java b/android/guava/src/com/google/common/base/ParametricNullness.java new file mode 100644 index 000000000000..5b595adb3ffb --- /dev/null +++ b/android/guava/src/com/google/common/base/ParametricNullness.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2021 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.base; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.google.common.annotations.GwtCompatible; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Marks a "top-level" type-variable usage as the closest we can get to "non-nullable when + * non-nullable; nullable when nullable" (like the Android {@code + * NullFromTypeParam}). + * + *

    Consumers of this annotation include: + * + *

      + *
    • Kotlin, for which it makes the type-variable usage (a) a Kotlin platform type when the type + * argument is non-nullable and (b) nullable when the type argument is nullable. We use this + * to "undo" {@link ElementTypesAreNonnullByDefault}. + *
    • J2ObjC + *
    • {@code NullPointerTester}, at least in the Android backport (where the type-use annotations + * {@code NullPointerTester} would need are not available) and in case of JDK-8202469 + *
    + * + */ +@GwtCompatible +@Retention(RUNTIME) +@Target({FIELD, METHOD, PARAMETER}) +@javax.annotation.meta.TypeQualifierNickname +@javax.annotation.Nonnull(when = javax.annotation.meta.When.UNKNOWN) +@interface ParametricNullness {} diff --git a/android/guava/src/com/google/common/base/PatternCompiler.java b/android/guava/src/com/google/common/base/PatternCompiler.java index 813a25f65b86..72a45faae963 100644 --- a/android/guava/src/com/google/common/base/PatternCompiler.java +++ b/android/guava/src/com/google/common/base/PatternCompiler.java @@ -22,6 +22,7 @@ * java.util.ServiceLoader} mechanism. */ @GwtIncompatible +@ElementTypesAreNonnullByDefault interface PatternCompiler { /** * Compiles the given pattern. diff --git a/android/guava/src/com/google/common/base/Platform.java b/android/guava/src/com/google/common/base/Platform.java index 896e9db83033..703b8605b1d5 100644 --- a/android/guava/src/com/google/common/base/Platform.java +++ b/android/guava/src/com/google/common/base/Platform.java @@ -21,7 +21,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Methods factored out so that they can be emulated differently in GWT. @@ -29,6 +29,7 @@ * @author Jesse Wilson */ @GwtCompatible(emulated = true) +@ElementTypesAreNonnullByDefault final class Platform { private static final Logger logger = Logger.getLogger(Platform.class.getName()); private static final PatternCompiler patternCompiler = loadPatternCompiler(); @@ -54,7 +55,7 @@ static String formatCompact4Digits(double value) { return String.format(Locale.ROOT, "%.4g", value); } - static boolean stringIsNullOrEmpty(@NullableDecl String string) { + static boolean stringIsNullOrEmpty(@CheckForNull String string) { return string == null || string.isEmpty(); } @@ -64,7 +65,7 @@ static boolean stringIsNullOrEmpty(@NullableDecl String string) { * @param string the string to test and possibly return * @return {@code string} if it is not null; {@code ""} otherwise */ - static String nullToEmpty(@NullableDecl String string) { + static String nullToEmpty(@CheckForNull String string) { return (string == null) ? "" : string; } @@ -74,7 +75,8 @@ static String nullToEmpty(@NullableDecl String string) { * @param string the string to test and possibly return * @return {@code string} if it is not empty; {@code null} otherwise */ - static String emptyToNull(@NullableDecl String string) { + @CheckForNull + static String emptyToNull(@CheckForNull String string) { return stringIsNullOrEmpty(string) ? null : string; } diff --git a/android/guava/src/com/google/common/base/Preconditions.java b/android/guava/src/com/google/common/base/Preconditions.java index 38f665463f7a..13ff77b7f78d 100644 --- a/android/guava/src/com/google/common/base/Preconditions.java +++ b/android/guava/src/com/google/common/base/Preconditions.java @@ -15,13 +15,11 @@ package com.google.common.base; import static com.google.common.base.Strings.lenientFormat; -import static java.util.logging.Level.WARNING; import com.google.common.annotations.GwtCompatible; import com.google.errorprone.annotations.CanIgnoreReturnValue; -import java.util.logging.Logger; -import org.checkerframework.checker.nullness.compatqual.NonNullDecl; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Static convenience methods that help a method or constructor check whether it was invoked @@ -116,9 +114,12 @@ * @since 2.0 */ @GwtCompatible +@ElementTypesAreNonnullByDefault public final class Preconditions { private Preconditions() {} + // TODO(cpovirk): Standardize parameter names (expression vs. b, reference vs. obj). + /** * Ensures the truth of an expression involving one or more parameters to the calling method. * @@ -139,7 +140,7 @@ public static void checkArgument(boolean expression) { * string using {@link String#valueOf(Object)} * @throws IllegalArgumentException if {@code expression} is false */ - public static void checkArgument(boolean expression, @NullableDecl Object errorMessage) { + public static void checkArgument(boolean expression, @CheckForNull Object errorMessage) { if (!expression) { throw new IllegalArgumentException(String.valueOf(errorMessage)); } @@ -160,8 +161,8 @@ public static void checkArgument(boolean expression, @NullableDecl Object errorM */ public static void checkArgument( boolean expression, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object... errorMessageArgs) { + String errorMessageTemplate, + @CheckForNull @Nullable Object... errorMessageArgs) { if (!expression) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, errorMessageArgs)); } @@ -174,7 +175,7 @@ public static void checkArgument( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument(boolean b, @NullableDecl String errorMessageTemplate, char p1) { + public static void checkArgument(boolean b, String errorMessageTemplate, char p1) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1)); } @@ -187,7 +188,7 @@ public static void checkArgument(boolean b, @NullableDecl String errorMessageTem * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument(boolean b, @NullableDecl String errorMessageTemplate, int p1) { + public static void checkArgument(boolean b, String errorMessageTemplate, int p1) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1)); } @@ -200,7 +201,7 @@ public static void checkArgument(boolean b, @NullableDecl String errorMessageTem * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument(boolean b, @NullableDecl String errorMessageTemplate, long p1) { + public static void checkArgument(boolean b, String errorMessageTemplate, long p1) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1)); } @@ -214,7 +215,7 @@ public static void checkArgument(boolean b, @NullableDecl String errorMessageTem * @since 20.0 (varargs overload since 2.0) */ public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, @NullableDecl Object p1) { + boolean b, String errorMessageTemplate, @CheckForNull Object p1) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1)); } @@ -227,8 +228,7 @@ public static void checkArgument( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, char p1, char p2) { + public static void checkArgument(boolean b, String errorMessageTemplate, char p1, char p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -241,8 +241,7 @@ public static void checkArgument( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, char p1, int p2) { + public static void checkArgument(boolean b, String errorMessageTemplate, char p1, int p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -255,8 +254,7 @@ public static void checkArgument( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, char p1, long p2) { + public static void checkArgument(boolean b, String errorMessageTemplate, char p1, long p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -270,7 +268,7 @@ public static void checkArgument( * @since 20.0 (varargs overload since 2.0) */ public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, char p1, @NullableDecl Object p2) { + boolean b, String errorMessageTemplate, char p1, @CheckForNull Object p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -283,8 +281,7 @@ public static void checkArgument( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, int p1, char p2) { + public static void checkArgument(boolean b, String errorMessageTemplate, int p1, char p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -297,8 +294,7 @@ public static void checkArgument( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, int p1, int p2) { + public static void checkArgument(boolean b, String errorMessageTemplate, int p1, int p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -311,8 +307,7 @@ public static void checkArgument( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, int p1, long p2) { + public static void checkArgument(boolean b, String errorMessageTemplate, int p1, long p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -326,7 +321,7 @@ public static void checkArgument( * @since 20.0 (varargs overload since 2.0) */ public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, int p1, @NullableDecl Object p2) { + boolean b, String errorMessageTemplate, int p1, @CheckForNull Object p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -339,8 +334,7 @@ public static void checkArgument( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, long p1, char p2) { + public static void checkArgument(boolean b, String errorMessageTemplate, long p1, char p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -353,8 +347,7 @@ public static void checkArgument( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, long p1, int p2) { + public static void checkArgument(boolean b, String errorMessageTemplate, long p1, int p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -367,8 +360,7 @@ public static void checkArgument( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, long p1, long p2) { + public static void checkArgument(boolean b, String errorMessageTemplate, long p1, long p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -382,7 +374,7 @@ public static void checkArgument( * @since 20.0 (varargs overload since 2.0) */ public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, long p1, @NullableDecl Object p2) { + boolean b, String errorMessageTemplate, long p1, @CheckForNull Object p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -396,7 +388,7 @@ public static void checkArgument( * @since 20.0 (varargs overload since 2.0) */ public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, @NullableDecl Object p1, char p2) { + boolean b, String errorMessageTemplate, @CheckForNull Object p1, char p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -410,7 +402,7 @@ public static void checkArgument( * @since 20.0 (varargs overload since 2.0) */ public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, @NullableDecl Object p1, int p2) { + boolean b, String errorMessageTemplate, @CheckForNull Object p1, int p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -424,7 +416,7 @@ public static void checkArgument( * @since 20.0 (varargs overload since 2.0) */ public static void checkArgument( - boolean b, @NullableDecl String errorMessageTemplate, @NullableDecl Object p1, long p2) { + boolean b, String errorMessageTemplate, @CheckForNull Object p1, long p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -438,10 +430,7 @@ public static void checkArgument( * @since 20.0 (varargs overload since 2.0) */ public static void checkArgument( - boolean b, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - @NullableDecl Object p2) { + boolean b, String errorMessageTemplate, @CheckForNull Object p1, @CheckForNull Object p2) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -456,10 +445,10 @@ public static void checkArgument( */ public static void checkArgument( boolean b, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - @NullableDecl Object p2, - @NullableDecl Object p3) { + String errorMessageTemplate, + @CheckForNull Object p1, + @CheckForNull Object p2, + @CheckForNull Object p3) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2, p3)); } @@ -474,11 +463,11 @@ public static void checkArgument( */ public static void checkArgument( boolean b, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - @NullableDecl Object p2, - @NullableDecl Object p3, - @NullableDecl Object p4) { + String errorMessageTemplate, + @CheckForNull Object p1, + @CheckForNull Object p2, + @CheckForNull Object p3, + @CheckForNull Object p4) { if (!b) { throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2, p3, p4)); } @@ -508,7 +497,7 @@ public static void checkState(boolean expression) { * @throws IllegalStateException if {@code expression} is false * @see Verify#verify Verify.verify() */ - public static void checkState(boolean expression, @NullableDecl Object errorMessage) { + public static void checkState(boolean expression, @CheckForNull Object errorMessage) { if (!expression) { throw new IllegalStateException(String.valueOf(errorMessage)); } @@ -531,8 +520,16 @@ public static void checkState(boolean expression, @NullableDecl Object errorMess */ public static void checkState( boolean expression, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object... errorMessageArgs) { + /* + * TODO(cpovirk): Consider removing @CheckForNull here, as we've done with the other methods' + * errorMessageTemplate parameters: It it unlikely that callers intend for their string + * template to be null (though we do handle that case gracefully at runtime). I've left this + * one as it is because one of our users has defined a wrapper API around Preconditions, + * declaring a checkState method that accepts a possibly null template. So we'd need to update + * that user first. + */ + @CheckForNull String errorMessageTemplate, + @CheckForNull @Nullable Object... errorMessageArgs) { if (!expression) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, errorMessageArgs)); } @@ -546,7 +543,7 @@ public static void checkState( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState(boolean b, @NullableDecl String errorMessageTemplate, char p1) { + public static void checkState(boolean b, String errorMessageTemplate, char p1) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1)); } @@ -560,7 +557,7 @@ public static void checkState(boolean b, @NullableDecl String errorMessageTempla * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState(boolean b, @NullableDecl String errorMessageTemplate, int p1) { + public static void checkState(boolean b, String errorMessageTemplate, int p1) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1)); } @@ -574,7 +571,7 @@ public static void checkState(boolean b, @NullableDecl String errorMessageTempla * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState(boolean b, @NullableDecl String errorMessageTemplate, long p1) { + public static void checkState(boolean b, String errorMessageTemplate, long p1) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1)); } @@ -588,8 +585,7 @@ public static void checkState(boolean b, @NullableDecl String errorMessageTempla * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, @NullableDecl Object p1) { + public static void checkState(boolean b, String errorMessageTemplate, @CheckForNull Object p1) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1)); } @@ -603,8 +599,7 @@ public static void checkState( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, char p1, char p2) { + public static void checkState(boolean b, String errorMessageTemplate, char p1, char p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -618,8 +613,7 @@ public static void checkState( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, char p1, int p2) { + public static void checkState(boolean b, String errorMessageTemplate, char p1, int p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -633,8 +627,7 @@ public static void checkState( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, char p1, long p2) { + public static void checkState(boolean b, String errorMessageTemplate, char p1, long p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -649,7 +642,7 @@ public static void checkState( * @since 20.0 (varargs overload since 2.0) */ public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, char p1, @NullableDecl Object p2) { + boolean b, String errorMessageTemplate, char p1, @CheckForNull Object p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -663,8 +656,7 @@ public static void checkState( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, int p1, char p2) { + public static void checkState(boolean b, String errorMessageTemplate, int p1, char p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -678,8 +670,7 @@ public static void checkState( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, int p1, int p2) { + public static void checkState(boolean b, String errorMessageTemplate, int p1, int p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -693,8 +684,7 @@ public static void checkState( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, int p1, long p2) { + public static void checkState(boolean b, String errorMessageTemplate, int p1, long p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -709,7 +699,7 @@ public static void checkState( * @since 20.0 (varargs overload since 2.0) */ public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, int p1, @NullableDecl Object p2) { + boolean b, String errorMessageTemplate, int p1, @CheckForNull Object p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -723,8 +713,7 @@ public static void checkState( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, long p1, char p2) { + public static void checkState(boolean b, String errorMessageTemplate, long p1, char p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -738,8 +727,7 @@ public static void checkState( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, long p1, int p2) { + public static void checkState(boolean b, String errorMessageTemplate, long p1, int p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -753,8 +741,7 @@ public static void checkState( * * @since 20.0 (varargs overload since 2.0) */ - public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, long p1, long p2) { + public static void checkState(boolean b, String errorMessageTemplate, long p1, long p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -769,7 +756,7 @@ public static void checkState( * @since 20.0 (varargs overload since 2.0) */ public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, long p1, @NullableDecl Object p2) { + boolean b, String errorMessageTemplate, long p1, @CheckForNull Object p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -784,7 +771,7 @@ public static void checkState( * @since 20.0 (varargs overload since 2.0) */ public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, @NullableDecl Object p1, char p2) { + boolean b, String errorMessageTemplate, @CheckForNull Object p1, char p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -799,7 +786,7 @@ public static void checkState( * @since 20.0 (varargs overload since 2.0) */ public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, @NullableDecl Object p1, int p2) { + boolean b, String errorMessageTemplate, @CheckForNull Object p1, int p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -814,7 +801,7 @@ public static void checkState( * @since 20.0 (varargs overload since 2.0) */ public static void checkState( - boolean b, @NullableDecl String errorMessageTemplate, @NullableDecl Object p1, long p2) { + boolean b, String errorMessageTemplate, @CheckForNull Object p1, long p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -829,10 +816,7 @@ public static void checkState( * @since 20.0 (varargs overload since 2.0) */ public static void checkState( - boolean b, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - @NullableDecl Object p2) { + boolean b, String errorMessageTemplate, @CheckForNull Object p1, @CheckForNull Object p2) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -848,10 +832,10 @@ public static void checkState( */ public static void checkState( boolean b, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - @NullableDecl Object p2, - @NullableDecl Object p3) { + String errorMessageTemplate, + @CheckForNull Object p1, + @CheckForNull Object p2, + @CheckForNull Object p3) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2, p3)); } @@ -867,16 +851,30 @@ public static void checkState( */ public static void checkState( boolean b, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - @NullableDecl Object p2, - @NullableDecl Object p3, - @NullableDecl Object p4) { + String errorMessageTemplate, + @CheckForNull Object p1, + @CheckForNull Object p2, + @CheckForNull Object p3, + @CheckForNull Object p4) { if (!b) { throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2, p3, p4)); } } + /* + * Preconditions.checkNotNull is *intended* for performing eager null checks on parameters that a + * nullness checker can already "prove" are non-null. That means that the first parameter to + * checkNotNull *should* be annotated to require it to be non-null. + * + * However, for a variety of reasons, Google developers have written a ton of code over the past + * decade that assumes that they can use checkNotNull for non-precondition checks. I had hoped to + * take a principled stand on this, but the amount of such code is simply overwhelming. To avoid + * creating a lot of compile errors that users would not find to be informative, we're giving in + * and allowing callers to pass arguments that a nullness checker believes could be null. + * + * We still encourage people to use requireNonNull over checkNotNull for non-precondition checks. + */ + /** * Ensures that an object reference passed as a parameter to the calling method is not null. * @@ -886,8 +884,7 @@ public static void checkState( * @see Verify#verifyNotNull Verify.verifyNotNull() */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull(@NonNullDecl T reference) { + public static T checkNotNull(@CheckForNull T reference) { if (reference == null) { throw new NullPointerException(); } @@ -905,9 +902,7 @@ public static T checkNotNull(@NonNullDecl T reference) { * @see Verify#verifyNotNull Verify.verifyNotNull() */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T reference, @NullableDecl Object errorMessage) { + public static T checkNotNull(@CheckForNull T reference, @CheckForNull Object errorMessage) { if (reference == null) { throw new NullPointerException(String.valueOf(errorMessage)); } @@ -930,11 +925,10 @@ public static T checkNotNull( * @see Verify#verifyNotNull Verify.verifyNotNull() */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T reference, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object... errorMessageArgs) { + public static T checkNotNull( + @CheckForNull T reference, + String errorMessageTemplate, + @CheckForNull @Nullable Object... errorMessageArgs) { if (reference == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, errorMessageArgs)); } @@ -949,9 +943,7 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, char p1) { + public static T checkNotNull(@CheckForNull T obj, String errorMessageTemplate, char p1) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1)); } @@ -966,9 +958,7 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, int p1) { + public static T checkNotNull(@CheckForNull T obj, String errorMessageTemplate, int p1) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1)); } @@ -983,9 +973,7 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, long p1) { + public static T checkNotNull(@CheckForNull T obj, String errorMessageTemplate, long p1) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1)); } @@ -1000,9 +988,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, @NullableDecl Object p1) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, @CheckForNull Object p1) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1)); } @@ -1017,9 +1004,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, char p1, char p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, char p1, char p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1034,9 +1020,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, char p1, int p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, char p1, int p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1051,9 +1036,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, char p1, long p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, char p1, long p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1068,12 +1052,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, - @NullableDecl String errorMessageTemplate, - char p1, - @NullableDecl Object p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, char p1, @CheckForNull Object p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1088,9 +1068,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, int p1, char p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, int p1, char p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1105,9 +1084,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, int p1, int p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, int p1, int p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1122,9 +1100,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, int p1, long p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, int p1, long p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1139,12 +1116,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, - @NullableDecl String errorMessageTemplate, - int p1, - @NullableDecl Object p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, int p1, @CheckForNull Object p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1159,9 +1132,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, long p1, char p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, long p1, char p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1176,9 +1148,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, long p1, int p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, long p1, int p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1193,9 +1164,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, @NullableDecl String errorMessageTemplate, long p1, long p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, long p1, long p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1210,12 +1180,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, - @NullableDecl String errorMessageTemplate, - long p1, - @NullableDecl Object p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, long p1, @CheckForNull Object p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1230,12 +1196,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - char p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, @CheckForNull Object p1, char p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1250,12 +1212,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - int p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, @CheckForNull Object p1, int p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1270,12 +1228,8 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - long p2) { + public static T checkNotNull( + @CheckForNull T obj, String errorMessageTemplate, @CheckForNull Object p1, long p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1290,12 +1244,11 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - @NullableDecl Object p2) { + public static T checkNotNull( + @CheckForNull T obj, + String errorMessageTemplate, + @CheckForNull Object p1, + @CheckForNull Object p2) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2)); } @@ -1310,13 +1263,12 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - @NullableDecl Object p2, - @NullableDecl Object p3) { + public static T checkNotNull( + @CheckForNull T obj, + String errorMessageTemplate, + @CheckForNull Object p1, + @CheckForNull Object p2, + @CheckForNull Object p3) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2, p3)); } @@ -1331,14 +1283,13 @@ public static T checkNotNull( * @since 20.0 (varargs overload since 2.0) */ @CanIgnoreReturnValue - @NonNullDecl - public static T checkNotNull( - @NonNullDecl T obj, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object p1, - @NullableDecl Object p2, - @NullableDecl Object p3, - @NullableDecl Object p4) { + public static T checkNotNull( + @CheckForNull T obj, + String errorMessageTemplate, + @CheckForNull Object p1, + @CheckForNull Object p2, + @CheckForNull Object p3, + @CheckForNull Object p4) { if (obj == null) { throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2, p3, p4)); } @@ -1398,7 +1349,7 @@ public static int checkElementIndex(int index, int size) { * @throws IllegalArgumentException if {@code size} is negative */ @CanIgnoreReturnValue - public static int checkElementIndex(int index, int size, @NullableDecl String desc) { + public static int checkElementIndex(int index, int size, String desc) { // Carefully optimized for execution by hotspot (explanatory comment above) if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(badElementIndex(index, size, desc)); @@ -1406,7 +1357,7 @@ public static int checkElementIndex(int index, int size, @NullableDecl String de return index; } - private static String badElementIndex(int index, int size, @NullableDecl String desc) { + private static String badElementIndex(int index, int size, String desc) { if (index < 0) { return lenientFormat("%s (%s) must not be negative", desc, index); } else if (size < 0) { @@ -1443,7 +1394,7 @@ public static int checkPositionIndex(int index, int size) { * @throws IllegalArgumentException if {@code size} is negative */ @CanIgnoreReturnValue - public static int checkPositionIndex(int index, int size, @NullableDecl String desc) { + public static int checkPositionIndex(int index, int size, String desc) { // Carefully optimized for execution by hotspot (explanatory comment above) if (index < 0 || index > size) { throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc)); @@ -1451,7 +1402,7 @@ public static int checkPositionIndex(int index, int size, @NullableDecl String d return index; } - private static String badPositionIndex(int index, int size, @NullableDecl String desc) { + private static String badPositionIndex(int index, int size, String desc) { if (index < 0) { return lenientFormat("%s (%s) must not be negative", desc, index); } else if (size < 0) { @@ -1490,21 +1441,4 @@ private static String badPositionIndexes(int start, int end, int size) { // end < start return lenientFormat("end index (%s) must not be less than start index (%s)", end, start); } - - static { - try { - Java8Usage.performCheck(); - } catch (Throwable underlying) { - Exception toLog = - new Exception( - "Guava will drop support for Java 7 in 2021. Please let us know if this will cause" - + " you problems: https://github.com/google/guava/issues/5269", - underlying); - Logger.getLogger(Preconditions.class.getName()) - .log( - WARNING, - "Java 7 compatibility warning: See https://github.com/google/guava/issues/5269", - toLog); - } - } } diff --git a/android/guava/src/com/google/common/base/Predicate.java b/android/guava/src/com/google/common/base/Predicate.java index e0627255012f..35d57a6018a2 100644 --- a/android/guava/src/com/google/common/base/Predicate.java +++ b/android/guava/src/com/google/common/base/Predicate.java @@ -16,7 +16,8 @@ import com.google.common.annotations.GwtCompatible; import com.google.errorprone.annotations.CanIgnoreReturnValue; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Determines a true or false value for a given input; a pre-Java-8 version of {@link @@ -45,7 +46,8 @@ * @since 2.0 */ @GwtCompatible -public interface Predicate { +@ElementTypesAreNonnullByDefault +public interface Predicate { /** * Returns the result of applying this predicate to {@code input} (Java 8 users, see notes in the * class documentation above). This method is generally expected, but not absolutely @@ -62,7 +64,7 @@ public interface Predicate { * arguments */ @CanIgnoreReturnValue - boolean apply(@NullableDecl T input); + boolean apply(@ParametricNullness T input); /** * Indicates whether another object is equal to this predicate. @@ -75,5 +77,5 @@ public interface Predicate { * predicates are known not to be interchangeable. */ @Override - boolean equals(@NullableDecl Object object); + boolean equals(@CheckForNull Object object); } diff --git a/android/guava/src/com/google/common/base/Predicates.java b/android/guava/src/com/google/common/base/Predicates.java index 9c8f1e5ea256..dc487fc56ffa 100644 --- a/android/guava/src/com/google/common/base/Predicates.java +++ b/android/guava/src/com/google/common/base/Predicates.java @@ -25,7 +25,8 @@ import java.util.Collection; import java.util.List; import java.util.regex.Pattern; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Static utility methods pertaining to {@code Predicate} instances. @@ -39,6 +40,7 @@ * @since 2.0 */ @GwtCompatible(emulated = true) +@ElementTypesAreNonnullByDefault public final class Predicates { private Predicates() {} @@ -47,13 +49,13 @@ private Predicates() {} /** Returns a predicate that always evaluates to {@code true}. */ @GwtCompatible(serializable = true) - public static Predicate alwaysTrue() { + public static Predicate alwaysTrue() { return ObjectPredicate.ALWAYS_TRUE.withNarrowedType(); } /** Returns a predicate that always evaluates to {@code false}. */ @GwtCompatible(serializable = true) - public static Predicate alwaysFalse() { + public static Predicate alwaysFalse() { return ObjectPredicate.ALWAYS_FALSE.withNarrowedType(); } @@ -62,7 +64,7 @@ public static Predicate alwaysFalse() { * null. */ @GwtCompatible(serializable = true) - public static Predicate isNull() { + public static Predicate isNull() { return ObjectPredicate.IS_NULL.withNarrowedType(); } @@ -71,7 +73,7 @@ public static Predicate isNull() { * null. */ @GwtCompatible(serializable = true) - public static Predicate notNull() { + public static Predicate notNull() { return ObjectPredicate.NOT_NULL.withNarrowedType(); } @@ -79,8 +81,8 @@ public static Predicate notNull() { * Returns a predicate that evaluates to {@code true} if the given predicate evaluates to {@code * false}. */ - public static Predicate not(Predicate predicate) { - return new NotPredicate(predicate); + public static Predicate not(Predicate predicate) { + return new NotPredicate<>(predicate); } /** @@ -90,8 +92,9 @@ public static Predicate not(Predicate predicate) { * changes to it won't alter the behavior of this predicate. If {@code components} is empty, the * returned predicate will always evaluate to {@code true}. */ - public static Predicate and(Iterable> components) { - return new AndPredicate(defensiveCopy(components)); + public static Predicate and( + Iterable> components) { + return new AndPredicate<>(defensiveCopy(components)); } /** @@ -102,7 +105,7 @@ public static Predicate and(Iterable> comp * returned predicate will always evaluate to {@code true}. */ @SafeVarargs - public static Predicate and(Predicate... components) { + public static Predicate and(Predicate... components) { return new AndPredicate(defensiveCopy(components)); } @@ -111,8 +114,9 @@ public static Predicate and(Predicate... components) { * true}. The components are evaluated in order, and evaluation will be "short-circuited" as soon * as a false predicate is found. */ - public static Predicate and(Predicate first, Predicate second) { - return new AndPredicate(Predicates.asList(checkNotNull(first), checkNotNull(second))); + public static Predicate and( + Predicate first, Predicate second) { + return new AndPredicate<>(Predicates.asList(checkNotNull(first), checkNotNull(second))); } /** @@ -122,8 +126,9 @@ public static Predicate and(Predicate first, Predicate Predicate or(Iterable> components) { - return new OrPredicate(defensiveCopy(components)); + public static Predicate or( + Iterable> components) { + return new OrPredicate<>(defensiveCopy(components)); } /** @@ -134,7 +139,7 @@ public static Predicate or(Iterable> compo * returned predicate will always evaluate to {@code false}. */ @SafeVarargs - public static Predicate or(Predicate... components) { + public static Predicate or(Predicate... components) { return new OrPredicate(defensiveCopy(components)); } @@ -143,16 +148,19 @@ public static Predicate or(Predicate... components) { * {@code true}. The components are evaluated in order, and evaluation will be "short-circuited" * as soon as a true predicate is found. */ - public static Predicate or(Predicate first, Predicate second) { - return new OrPredicate(Predicates.asList(checkNotNull(first), checkNotNull(second))); + public static Predicate or( + Predicate first, Predicate second) { + return new OrPredicate<>(Predicates.asList(checkNotNull(first), checkNotNull(second))); } /** * Returns a predicate that evaluates to {@code true} if the object being tested {@code equals()} * the given target or both are null. */ - public static Predicate equalTo(@NullableDecl T target) { - return (target == null) ? Predicates.isNull() : new IsEqualToPredicate(target); + public static Predicate equalTo(@ParametricNullness T target) { + return (target == null) + ? Predicates.isNull() + : new IsEqualToPredicate(target).withNarrowedType(); } /** @@ -169,8 +177,8 @@ public static Predicate equalTo(@NullableDecl T target) { * instances {@code Lists.newArrayList(1)} and {@code Arrays.asList(1)}. */ @GwtIncompatible // Class.isInstance - public static Predicate instanceOf(Class clazz) { - return new InstanceOfPredicate(clazz); + public static Predicate instanceOf(Class clazz) { + return new InstanceOfPredicate<>(clazz); } /** @@ -204,8 +212,8 @@ public static Predicate> subtypeOf(Class clazz) { * * @param target the collection that may contain the function input */ - public static Predicate in(Collection target) { - return new InPredicate(target); + public static Predicate in(Collection target) { + return new InPredicate<>(target); } /** @@ -214,7 +222,7 @@ public static Predicate in(Collection target) { * * @return the composition of the provided function and predicate */ - public static Predicate compose( + public static Predicate compose( Predicate predicate, Function function) { return new CompositionPredicate<>(predicate, function); } @@ -247,11 +255,11 @@ public static Predicate contains(Pattern pattern) { // End public API, begin private implementation classes. // Package private for GWT serialization. - enum ObjectPredicate implements Predicate { + enum ObjectPredicate implements Predicate<@Nullable Object> { /** @see Predicates#alwaysTrue() */ ALWAYS_TRUE { @Override - public boolean apply(@NullableDecl Object o) { + public boolean apply(@CheckForNull Object o) { return true; } @@ -263,7 +271,7 @@ public String toString() { /** @see Predicates#alwaysFalse() */ ALWAYS_FALSE { @Override - public boolean apply(@NullableDecl Object o) { + public boolean apply(@CheckForNull Object o) { return false; } @@ -275,7 +283,7 @@ public String toString() { /** @see Predicates#isNull() */ IS_NULL { @Override - public boolean apply(@NullableDecl Object o) { + public boolean apply(@CheckForNull Object o) { return o == null; } @@ -287,7 +295,7 @@ public String toString() { /** @see Predicates#notNull() */ NOT_NULL { @Override - public boolean apply(@NullableDecl Object o) { + public boolean apply(@CheckForNull Object o) { return o != null; } @@ -298,13 +306,14 @@ public String toString() { }; @SuppressWarnings("unchecked") // safe contravariant cast - Predicate withNarrowedType() { + Predicate withNarrowedType() { return (Predicate) this; } } /** @see Predicates#not(Predicate) */ - private static class NotPredicate implements Predicate, Serializable { + private static class NotPredicate + implements Predicate, Serializable { final Predicate predicate; NotPredicate(Predicate predicate) { @@ -312,7 +321,7 @@ private static class NotPredicate implements Predicate, Serializable { } @Override - public boolean apply(@NullableDecl T t) { + public boolean apply(@ParametricNullness T t) { return !predicate.apply(t); } @@ -322,7 +331,7 @@ public int hashCode() { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof NotPredicate) { NotPredicate that = (NotPredicate) obj; return predicate.equals(that.predicate); @@ -339,7 +348,8 @@ public String toString() { } /** @see Predicates#and(Iterable) */ - private static class AndPredicate implements Predicate, Serializable { + private static class AndPredicate + implements Predicate, Serializable { private final List> components; private AndPredicate(List> components) { @@ -347,7 +357,7 @@ private AndPredicate(List> components) { } @Override - public boolean apply(@NullableDecl T t) { + public boolean apply(@ParametricNullness T t) { // Avoid using the Iterator to avoid generating garbage (issue 820). for (int i = 0; i < components.size(); i++) { if (!components.get(i).apply(t)) { @@ -364,7 +374,7 @@ public int hashCode() { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof AndPredicate) { AndPredicate that = (AndPredicate) obj; return components.equals(that.components); @@ -381,7 +391,8 @@ public String toString() { } /** @see Predicates#or(Iterable) */ - private static class OrPredicate implements Predicate, Serializable { + private static class OrPredicate + implements Predicate, Serializable { private final List> components; private OrPredicate(List> components) { @@ -389,7 +400,7 @@ private OrPredicate(List> components) { } @Override - public boolean apply(@NullableDecl T t) { + public boolean apply(@ParametricNullness T t) { // Avoid using the Iterator to avoid generating garbage (issue 820). for (int i = 0; i < components.size(); i++) { if (components.get(i).apply(t)) { @@ -406,7 +417,7 @@ public int hashCode() { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof OrPredicate) { OrPredicate that = (OrPredicate) obj; return components.equals(that.components); @@ -436,16 +447,16 @@ private static String toStringHelper(String methodName, Iterable components) } /** @see Predicates#equalTo(Object) */ - private static class IsEqualToPredicate implements Predicate, Serializable { - private final T target; + private static class IsEqualToPredicate implements Predicate<@Nullable Object>, Serializable { + private final Object target; - private IsEqualToPredicate(T target) { + private IsEqualToPredicate(Object target) { this.target = target; } @Override - public boolean apply(T t) { - return target.equals(t); + public boolean apply(@CheckForNull Object o) { + return target.equals(o); } @Override @@ -454,9 +465,9 @@ public int hashCode() { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof IsEqualToPredicate) { - IsEqualToPredicate that = (IsEqualToPredicate) obj; + IsEqualToPredicate that = (IsEqualToPredicate) obj; return target.equals(that.target); } return false; @@ -468,11 +479,17 @@ public String toString() { } private static final long serialVersionUID = 0; + + @SuppressWarnings("unchecked") // safe contravariant cast + Predicate withNarrowedType() { + return (Predicate) this; + } } /** @see Predicates#instanceOf(Class) */ @GwtIncompatible // Class.isInstance - private static class InstanceOfPredicate implements Predicate, Serializable { + private static class InstanceOfPredicate + implements Predicate, Serializable { private final Class clazz; private InstanceOfPredicate(Class clazz) { @@ -480,7 +497,7 @@ private InstanceOfPredicate(Class clazz) { } @Override - public boolean apply(@NullableDecl Object o) { + public boolean apply(@ParametricNullness T o) { return clazz.isInstance(o); } @@ -490,9 +507,9 @@ public int hashCode() { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof InstanceOfPredicate) { - InstanceOfPredicate that = (InstanceOfPredicate) obj; + InstanceOfPredicate that = (InstanceOfPredicate) obj; return clazz == that.clazz; } return false; @@ -526,7 +543,7 @@ public int hashCode() { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof SubtypeOfPredicate) { SubtypeOfPredicate that = (SubtypeOfPredicate) obj; return clazz == that.clazz; @@ -543,7 +560,8 @@ public String toString() { } /** @see Predicates#in(Collection) */ - private static class InPredicate implements Predicate, Serializable { + private static class InPredicate + implements Predicate, Serializable { private final Collection target; private InPredicate(Collection target) { @@ -551,7 +569,7 @@ private InPredicate(Collection target) { } @Override - public boolean apply(@NullableDecl T t) { + public boolean apply(@ParametricNullness T t) { try { return target.contains(t); } catch (NullPointerException | ClassCastException e) { @@ -560,7 +578,7 @@ public boolean apply(@NullableDecl T t) { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof InPredicate) { InPredicate that = (InPredicate) obj; return target.equals(that.target); @@ -582,7 +600,8 @@ public String toString() { } /** @see Predicates#compose(Predicate, Function) */ - private static class CompositionPredicate implements Predicate, Serializable { + private static class CompositionPredicate + implements Predicate, Serializable { final Predicate p; final Function f; @@ -592,12 +611,12 @@ private CompositionPredicate(Predicate p, Function f) { } @Override - public boolean apply(@NullableDecl A a) { + public boolean apply(@ParametricNullness A a) { return p.apply(f.apply(a)); } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof CompositionPredicate) { CompositionPredicate that = (CompositionPredicate) obj; return f.equals(that.f) && p.equals(that.p); @@ -642,7 +661,7 @@ public int hashCode() { } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof ContainsPatternPredicate) { ContainsPatternPredicate that = (ContainsPatternPredicate) obj; @@ -683,7 +702,7 @@ public String toString() { private static final long serialVersionUID = 0; } - private static List> asList( + private static List> asList( Predicate first, Predicate second) { // TODO(kevinb): understand why we still get a warning despite @SafeVarargs! return Arrays.>asList(first, second); @@ -694,7 +713,7 @@ private static List defensiveCopy(T... array) { } static List defensiveCopy(Iterable iterable) { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); for (T element : iterable) { list.add(checkNotNull(element)); } diff --git a/android/guava/src/com/google/common/base/Present.java b/android/guava/src/com/google/common/base/Present.java index d33eb8e38567..4e62da29e93b 100644 --- a/android/guava/src/com/google/common/base/Present.java +++ b/android/guava/src/com/google/common/base/Present.java @@ -19,10 +19,11 @@ import com.google.common.annotations.GwtCompatible; import java.util.Collections; import java.util.Set; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** Implementation of an {@link Optional} containing a reference. */ @GwtCompatible +@ElementTypesAreNonnullByDefault final class Present extends Optional { private final T reference; @@ -70,14 +71,14 @@ public Set asSet() { @Override public Optional transform(Function function) { - return new Present( + return new Present<>( checkNotNull( function.apply(reference), "the Function passed to Optional.transform() must not return null.")); } @Override - public boolean equals(@NullableDecl Object object) { + public boolean equals(@CheckForNull Object object) { if (object instanceof Present) { Present other = (Present) object; return reference.equals(other.reference); diff --git a/android/guava/src/com/google/common/base/SmallCharMatcher.java b/android/guava/src/com/google/common/base/SmallCharMatcher.java index 1e565c858b96..f0e801b67118 100644 --- a/android/guava/src/com/google/common/base/SmallCharMatcher.java +++ b/android/guava/src/com/google/common/base/SmallCharMatcher.java @@ -26,6 +26,7 @@ * @author Christopher Swenson */ @GwtIncompatible // no precomputation is done in GWT +@ElementTypesAreNonnullByDefault final class SmallCharMatcher extends NamedFastMatcher { static final int MAX_SIZE = 1023; private final char[] table; diff --git a/android/guava/src/com/google/common/base/Splitter.java b/android/guava/src/com/google/common/base/Splitter.java index 150c2fe4d09c..bde2e0ec42f8 100644 --- a/android/guava/src/com/google/common/base/Splitter.java +++ b/android/guava/src/com/google/common/base/Splitter.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import java.util.regex.Pattern; +import javax.annotation.CheckForNull; /** * Extracts non-overlapping substrings from an input string, typically by recognizing appearances of @@ -97,6 +98,7 @@ * @since 1.0 */ @GwtCompatible(emulated = true) +@ElementTypesAreNonnullByDefault public final class Splitter { private final CharMatcher trimmer; private final boolean omitEmptyStrings; @@ -547,6 +549,7 @@ protected SplittingIterator(Splitter splitter, CharSequence toSplit) { this.toSplit = toSplit; } + @CheckForNull @Override protected String computeNext() { /* diff --git a/android/guava/src/com/google/common/base/StandardSystemProperty.java b/android/guava/src/com/google/common/base/StandardSystemProperty.java index bf86128e81a6..dc29792de782 100644 --- a/android/guava/src/com/google/common/base/StandardSystemProperty.java +++ b/android/guava/src/com/google/common/base/StandardSystemProperty.java @@ -15,7 +15,7 @@ package com.google.common.base; import com.google.common.annotations.GwtIncompatible; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Represents a {@linkplain System#getProperties() standard system property}. @@ -24,6 +24,7 @@ * @since 15.0 */ @GwtIncompatible // java.lang.System#getProperty +@ElementTypesAreNonnullByDefault public enum StandardSystemProperty { /** Java Runtime Environment version. */ @@ -152,7 +153,7 @@ public String key() { *
  • {@code jdk.module.*} (added in Java 9, optional) * */ - @NullableDecl + @CheckForNull public String value() { return System.getProperty(key); } diff --git a/android/guava/src/com/google/common/base/Stopwatch.java b/android/guava/src/com/google/common/base/Stopwatch.java index 4a6767d15e57..f76c098613a9 100644 --- a/android/guava/src/com/google/common/base/Stopwatch.java +++ b/android/guava/src/com/google/common/base/Stopwatch.java @@ -77,7 +77,7 @@ * Stopwatch.createStarted( * new Ticker() { * public long read() { - * return android.os.SystemClock.elapsedRealtimeNanos(); + * return android.os.SystemClock.elapsedRealtimeNanos(); // requires API Level 17 * } * }); * } @@ -85,8 +85,9 @@ * @author Kevin Bourrillion * @since 10.0 */ -@GwtCompatible +@GwtCompatible(emulated = true) @SuppressWarnings("GoodTime") // lots of violations +@ElementTypesAreNonnullByDefault public final class Stopwatch { private final Ticker ticker; private boolean isRunning; diff --git a/android/guava/src/com/google/common/base/Strings.java b/android/guava/src/com/google/common/base/Strings.java index 475851706e71..fa3626648d10 100644 --- a/android/guava/src/com/google/common/base/Strings.java +++ b/android/guava/src/com/google/common/base/Strings.java @@ -21,7 +21,8 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.VisibleForTesting; import java.util.logging.Logger; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Static utility methods pertaining to {@code String} or {@code CharSequence} instances. @@ -30,6 +31,7 @@ * @since 3.0 */ @GwtCompatible +@ElementTypesAreNonnullByDefault public final class Strings { private Strings() {} @@ -39,7 +41,7 @@ private Strings() {} * @param string the string to test and possibly return * @return {@code string} itself if it is non-null; {@code ""} if it is null */ - public static String nullToEmpty(@NullableDecl String string) { + public static String nullToEmpty(@CheckForNull String string) { return Platform.nullToEmpty(string); } @@ -49,8 +51,8 @@ public static String nullToEmpty(@NullableDecl String string) { * @param string the string to test and possibly return * @return {@code string} itself if it is nonempty; {@code null} if it is empty or null */ - @NullableDecl - public static String emptyToNull(@NullableDecl String string) { + @CheckForNull + public static String emptyToNull(@CheckForNull String string) { return Platform.emptyToNull(string); } @@ -65,7 +67,7 @@ public static String emptyToNull(@NullableDecl String string) { * @param string a string reference to check * @return {@code true} if the string is null or is the empty string */ - public static boolean isNullOrEmpty(@NullableDecl String string) { + public static boolean isNullOrEmpty(@CheckForNull String string) { return Platform.stringIsNullOrEmpty(string); } @@ -257,7 +259,8 @@ static boolean validSurrogatePairAt(CharSequence string, int index) { * @since 25.1 */ // TODO(diamondm) consider using Arrays.toString() for array parameters - public static String lenientFormat(@NullableDecl String template, @NullableDecl Object... args) { + public static String lenientFormat( + @CheckForNull String template, @CheckForNull @Nullable Object... args) { template = String.valueOf(template); // null -> "null" if (args == null) { @@ -297,7 +300,7 @@ public static String lenientFormat(@NullableDecl String template, @NullableDecl return builder.toString(); } - private static String lenientToString(@NullableDecl Object o) { + private static String lenientToString(@CheckForNull Object o) { if (o == null) { return "null"; } diff --git a/android/guava/src/com/google/common/base/Supplier.java b/android/guava/src/com/google/common/base/Supplier.java index 662bf1f664df..f9e1e34f17a0 100644 --- a/android/guava/src/com/google/common/base/Supplier.java +++ b/android/guava/src/com/google/common/base/Supplier.java @@ -16,6 +16,7 @@ import com.google.common.annotations.GwtCompatible; import com.google.errorprone.annotations.CanIgnoreReturnValue; +import org.checkerframework.checker.nullness.qual.Nullable; /** * A class that can supply objects of a single type; a pre-Java-8 version of {@link @@ -45,7 +46,8 @@ * @since 2.0 */ @GwtCompatible -public interface Supplier { +@ElementTypesAreNonnullByDefault +public interface Supplier { /** * Retrieves an instance of the appropriate type. The returned object may or may not be a new * instance, depending on the implementation. @@ -53,5 +55,6 @@ public interface Supplier { * @return an instance of the appropriate type */ @CanIgnoreReturnValue + @ParametricNullness T get(); } diff --git a/android/guava/src/com/google/common/base/Suppliers.java b/android/guava/src/com/google/common/base/Suppliers.java index da1490da2d7c..6ced905b988d 100644 --- a/android/guava/src/com/google/common/base/Suppliers.java +++ b/android/guava/src/com/google/common/base/Suppliers.java @@ -14,14 +14,17 @@ package com.google.common.base; +import static com.google.common.base.NullnessCasts.uncheckedCastNullableTToT; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.requireNonNull; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.VisibleForTesting; import java.io.Serializable; import java.util.concurrent.TimeUnit; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Useful suppliers. @@ -33,6 +36,7 @@ * @since 2.0 */ @GwtCompatible +@ElementTypesAreNonnullByDefault public final class Suppliers { private Suppliers() {} @@ -42,11 +46,13 @@ private Suppliers() {} * and then applying {@code function} to that value. Note that the resulting supplier will not * call {@code supplier} or invoke {@code function} until it is called. */ - public static Supplier compose(Function function, Supplier supplier) { + public static Supplier compose( + Function function, Supplier supplier) { return new SupplierComposition<>(function, supplier); } - private static class SupplierComposition implements Supplier, Serializable { + private static class SupplierComposition + implements Supplier, Serializable { final Function function; final Supplier supplier; @@ -56,12 +62,13 @@ private static class SupplierComposition implements Supplier, Serializa } @Override + @ParametricNullness public T get() { return function.apply(supplier.get()); } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof SupplierComposition) { SupplierComposition that = (SupplierComposition) obj; return function.equals(that.function) && supplier.equals(that.supplier); @@ -98,7 +105,7 @@ public String toString() { *

    If {@code delegate} is an instance created by an earlier call to {@code memoize}, it is * returned directly. */ - public static Supplier memoize(Supplier delegate) { + public static Supplier memoize(Supplier delegate) { if (delegate instanceof NonSerializableMemoizingSupplier || delegate instanceof MemoizingSupplier) { return delegate; @@ -109,18 +116,19 @@ public static Supplier memoize(Supplier delegate) { } @VisibleForTesting - static class MemoizingSupplier implements Supplier, Serializable { + static class MemoizingSupplier implements Supplier, Serializable { final Supplier delegate; transient volatile boolean initialized; // "value" does not need to be volatile; visibility piggy-backs // on volatile read of "initialized". - @NullableDecl transient T value; + @CheckForNull transient T value; MemoizingSupplier(Supplier delegate) { this.delegate = checkNotNull(delegate); } @Override + @ParametricNullness public T get() { // A 2-field variant of Double Checked Locking. if (!initialized) { @@ -133,7 +141,8 @@ public T get() { } } } - return value; + // This is safe because we checked `initialized.` + return uncheckedCastNullableTToT(value); } @Override @@ -147,24 +156,31 @@ public String toString() { } @VisibleForTesting - static class NonSerializableMemoizingSupplier implements Supplier { - volatile Supplier delegate; + static class NonSerializableMemoizingSupplier implements Supplier { + @CheckForNull volatile Supplier delegate; volatile boolean initialized; // "value" does not need to be volatile; visibility piggy-backs // on volatile read of "initialized". - @NullableDecl T value; + @CheckForNull T value; NonSerializableMemoizingSupplier(Supplier delegate) { this.delegate = checkNotNull(delegate); } @Override + @ParametricNullness public T get() { // A 2-field variant of Double Checked Locking. if (!initialized) { synchronized (this) { if (!initialized) { - T t = delegate.get(); + /* + * requireNonNull is safe because we read and write `delegate` under synchronization. + * + * TODO(cpovirk): To avoid having to check for null, replace `delegate` with a singleton + * `Supplier` that always throws an exception. + */ + T t = requireNonNull(delegate).get(); value = t; initialized = true; // Release the delegate to GC. @@ -173,7 +189,8 @@ public T get() { } } } - return value; + // This is safe because we checked `initialized.` + return uncheckedCastNullableTToT(value); } @Override @@ -207,17 +224,18 @@ public String toString() { * @since 2.0 */ @SuppressWarnings("GoodTime") // should accept a java.time.Duration - public static Supplier memoizeWithExpiration( + public static Supplier memoizeWithExpiration( Supplier delegate, long duration, TimeUnit unit) { - return new ExpiringMemoizingSupplier(delegate, duration, unit); + return new ExpiringMemoizingSupplier<>(delegate, duration, unit); } @VisibleForTesting @SuppressWarnings("GoodTime") // lots of violations - static class ExpiringMemoizingSupplier implements Supplier, Serializable { + static class ExpiringMemoizingSupplier + implements Supplier, Serializable { final Supplier delegate; final long durationNanos; - @NullableDecl transient volatile T value; + @CheckForNull transient volatile T value; // The special value 0 means "not yet initialized". transient volatile long expirationNanos; @@ -228,6 +246,7 @@ static class ExpiringMemoizingSupplier implements Supplier, Serializable { } @Override + @ParametricNullness public T get() { // Another variant of Double Checked Locking. // @@ -250,7 +269,8 @@ public T get() { } } } - return value; + // This is safe because we checked `expirationNanos.` + return uncheckedCastNullableTToT(value); } @Override @@ -264,24 +284,27 @@ public String toString() { } /** Returns a supplier that always supplies {@code instance}. */ - public static Supplier ofInstance(@NullableDecl T instance) { - return new SupplierOfInstance(instance); + public static Supplier ofInstance( + @ParametricNullness T instance) { + return new SupplierOfInstance<>(instance); } - private static class SupplierOfInstance implements Supplier, Serializable { - @NullableDecl final T instance; + private static class SupplierOfInstance + implements Supplier, Serializable { + @ParametricNullness final T instance; - SupplierOfInstance(@NullableDecl T instance) { + SupplierOfInstance(@ParametricNullness T instance) { this.instance = instance; } @Override + @ParametricNullness public T get() { return instance; } @Override - public boolean equals(@NullableDecl Object obj) { + public boolean equals(@CheckForNull Object obj) { if (obj instanceof SupplierOfInstance) { SupplierOfInstance that = (SupplierOfInstance) obj; return Objects.equal(instance, that.instance); @@ -306,11 +329,13 @@ public String toString() { * Returns a supplier whose {@code get()} method synchronizes on {@code delegate} before calling * it, making it thread-safe. */ - public static Supplier synchronizedSupplier(Supplier delegate) { - return new ThreadSafeSupplier(delegate); + public static Supplier synchronizedSupplier( + Supplier delegate) { + return new ThreadSafeSupplier<>(delegate); } - private static class ThreadSafeSupplier implements Supplier, Serializable { + private static class ThreadSafeSupplier + implements Supplier, Serializable { final Supplier delegate; ThreadSafeSupplier(Supplier delegate) { @@ -318,6 +343,7 @@ private static class ThreadSafeSupplier implements Supplier, Serializable } @Override + @ParametricNullness public T get() { synchronized (delegate) { return delegate.get(); @@ -340,20 +366,21 @@ public String toString() { * * @since 8.0 */ - public static Function, T> supplierFunction() { + public static Function, T> supplierFunction() { @SuppressWarnings("unchecked") // implementation is "fully variant" SupplierFunction sf = (SupplierFunction) SupplierFunctionImpl.INSTANCE; return sf; } - private interface SupplierFunction extends Function, T> {} + private interface SupplierFunction extends Function, T> {} - private enum SupplierFunctionImpl implements SupplierFunction { + private enum SupplierFunctionImpl implements SupplierFunction<@Nullable Object> { INSTANCE; // Note: This makes T a "pass-through type" @Override - public Object apply(Supplier input) { + @CheckForNull + public Object apply(Supplier<@Nullable Object> input) { return input.get(); } diff --git a/android/guava/src/com/google/common/base/Throwables.java b/android/guava/src/com/google/common/base/Throwables.java index b2abb504402f..e45ce800cb63 100644 --- a/android/guava/src/com/google/common/base/Throwables.java +++ b/android/guava/src/com/google/common/base/Throwables.java @@ -17,8 +17,8 @@ import static com.google.common.base.Preconditions.checkNotNull; import static java.util.Arrays.asList; import static java.util.Collections.unmodifiableList; +import static java.util.Objects.requireNonNull; -import com.google.common.annotations.Beta; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.annotations.VisibleForTesting; @@ -32,7 +32,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Static utility methods pertaining to instances of {@link Throwable}. @@ -45,6 +45,7 @@ * @since 1.0 */ @GwtCompatible(emulated = true) +@ElementTypesAreNonnullByDefault public final class Throwables { private Throwables() {} @@ -99,7 +100,7 @@ public static void throwIfInstanceOf( @Deprecated @GwtIncompatible // throwIfInstanceOf public static void propagateIfInstanceOf( - @NullableDecl Throwable throwable, Class declaredType) throws X { + @CheckForNull Throwable throwable, Class declaredType) throws X { if (throwable != null) { throwIfInstanceOf(throwable, declaredType); } @@ -154,7 +155,7 @@ public static void throwIfUnchecked(Throwable throwable) { */ @Deprecated @GwtIncompatible - public static void propagateIfPossible(@NullableDecl Throwable throwable) { + public static void propagateIfPossible(@CheckForNull Throwable throwable) { if (throwable != null) { throwIfUnchecked(throwable); } @@ -180,7 +181,7 @@ public static void propagateIfPossible(@NullableDecl Throwable throwable) { */ @GwtIncompatible // propagateIfInstanceOf public static void propagateIfPossible( - @NullableDecl Throwable throwable, Class declaredType) throws X { + @CheckForNull Throwable throwable, Class declaredType) throws X { propagateIfInstanceOf(throwable, declaredType); propagateIfPossible(throwable); } @@ -198,7 +199,7 @@ public static void propagateIfPossible( */ @GwtIncompatible // propagateIfInstanceOf public static void propagateIfPossible( - @NullableDecl Throwable throwable, Class declaredType1, Class declaredType2) + @CheckForNull Throwable throwable, Class declaredType1, Class declaredType2) throws X1, X2 { checkNotNull(declaredType2); propagateIfInstanceOf(throwable, declaredType1); @@ -288,7 +289,6 @@ public static Throwable getRootCause(Throwable throwable) { * @return an unmodifiable list containing the cause chain starting with {@code throwable} * @throws IllegalArgumentException if there is a loop in the causal chain */ - @Beta // TODO(kevinb): decide best return type public static List getCausalChain(Throwable throwable) { checkNotNull(throwable); List causes = new ArrayList<>(4); @@ -328,8 +328,8 @@ public static List getCausalChain(Throwable throwable) { * ClassCastException}'s cause is {@code throwable}. * @since 22.0 */ - @Beta @GwtIncompatible // Class.cast(Object) + @CheckForNull public static X getCauseAs( Throwable throwable, Class expectedCauseType) { try { @@ -379,11 +379,12 @@ public static String getStackTraceAsString(Throwable throwable) { * exception's creation. * * @since 19.0 + * @deprecated This method is equivalent to {@link Throwable#getStackTrace()} on JDK versions past + * JDK 8 and on all Android versions. Use {@link Throwable#getStackTrace()} directly, or where + * possible use the {@code java.lang.StackWalker.walk} method introduced in JDK 9. */ - // TODO(cpovirk): Say something about the possibility that List access could fail at runtime? - @Beta + @Deprecated @GwtIncompatible // lazyStackTraceIsLazy, jlaStackTrace - // TODO(cpovirk): Consider making this available under GWT (slow implementation only). public static List lazyStackTrace(Throwable throwable) { return lazyStackTraceIsLazy() ? jlaStackTrace(throwable) @@ -395,15 +396,17 @@ public static List lazyStackTrace(Throwable throwable) { * documentation. * * @since 19.0 + * @deprecated This method always returns false on JDK versions past JDK 8 and on all Android + * versions. */ - @Beta + @Deprecated @GwtIncompatible // getStackTraceElementMethod public static boolean lazyStackTraceIsLazy() { return getStackTraceElementMethod != null && getStackTraceDepthMethod != null; } @GwtIncompatible // invokeAccessibleNonThrowingMethod - private static List jlaStackTrace(final Throwable t) { + private static List jlaStackTrace(Throwable t) { checkNotNull(t); /* * TODO(cpovirk): Consider optimizing iterator() to catch IOOBE instead of doing bounds checks. @@ -412,15 +415,22 @@ private static List jlaStackTrace(final Throwable t) { * AOSP grief. */ return new AbstractList() { + /* + * The following requireNonNull calls are safe because we use jlaStackTrace() only if + * lazyStackTraceIsLazy() returns true. + */ @Override public StackTraceElement get(int n) { return (StackTraceElement) - invokeAccessibleNonThrowingMethod(getStackTraceElementMethod, jla, t, n); + invokeAccessibleNonThrowingMethod( + requireNonNull(getStackTraceElementMethod), requireNonNull(jla), t, n); } @Override public int size() { - return (Integer) invokeAccessibleNonThrowingMethod(getStackTraceDepthMethod, jla, t); + return (Integer) + invokeAccessibleNonThrowingMethod( + requireNonNull(getStackTraceDepthMethod), requireNonNull(jla), t); } }; } @@ -448,7 +458,7 @@ private static Object invokeAccessibleNonThrowingMethod( /** Access to some fancy internal JVM internals. */ @GwtIncompatible // java.lang.reflect - @NullableDecl + @CheckForNull private static final Object jla = getJLA(); /** @@ -456,7 +466,7 @@ private static Object invokeAccessibleNonThrowingMethod( * find it when available. When this is null, use the slow way. */ @GwtIncompatible // java.lang.reflect - @NullableDecl + @CheckForNull private static final Method getStackTraceElementMethod = (jla == null) ? null : getGetMethod(); /** @@ -464,15 +474,15 @@ private static Object invokeAccessibleNonThrowingMethod( * when available. When this is null, use the slow way. */ @GwtIncompatible // java.lang.reflect - @NullableDecl - private static final Method getStackTraceDepthMethod = (jla == null) ? null : getSizeMethod(); + @CheckForNull + private static final Method getStackTraceDepthMethod = (jla == null) ? null : getSizeMethod(jla); /** * Returns the JavaLangAccess class that is present in all Sun JDKs. It is not allowed in * AppEngine, and not present in non-Sun JDKs. */ @GwtIncompatible // java.lang.reflect - @NullableDecl + @CheckForNull private static Object getJLA() { try { /* @@ -498,7 +508,7 @@ private static Object getJLA() { * method cannot be found (it is only to be found in fairly recent JDKs). */ @GwtIncompatible // java.lang.reflect - @NullableDecl + @CheckForNull private static Method getGetMethod() { return getJlaMethod("getStackTraceElement", Throwable.class, int.class); } @@ -513,14 +523,14 @@ private static Method getGetMethod() { * UnsupportedOperationException. */ @GwtIncompatible // java.lang.reflect - @NullableDecl - private static Method getSizeMethod() { + @CheckForNull + private static Method getSizeMethod(Object jla) { try { Method getStackTraceDepth = getJlaMethod("getStackTraceDepth", Throwable.class); if (getStackTraceDepth == null) { return null; } - getStackTraceDepth.invoke(getJLA(), new Throwable()); + getStackTraceDepth.invoke(jla, new Throwable()); return getStackTraceDepth; } catch (UnsupportedOperationException | IllegalAccessException | InvocationTargetException e) { return null; @@ -528,7 +538,7 @@ private static Method getSizeMethod() { } @GwtIncompatible // java.lang.reflect - @NullableDecl + @CheckForNull private static Method getJlaMethod(String name, Class... parameterTypes) throws ThreadDeath { try { return Class.forName(JAVA_LANG_ACCESS_CLASSNAME, false, null).getMethod(name, parameterTypes); diff --git a/android/guava/src/com/google/common/base/Ticker.java b/android/guava/src/com/google/common/base/Ticker.java index a53883b46ed7..d898735c028f 100644 --- a/android/guava/src/com/google/common/base/Ticker.java +++ b/android/guava/src/com/google/common/base/Ticker.java @@ -28,6 +28,7 @@ * source-compatible since 9.0) */ @GwtCompatible +@ElementTypesAreNonnullByDefault public abstract class Ticker { /** Constructor for use by subclasses. */ protected Ticker() {} diff --git a/android/guava/src/com/google/common/base/Utf8.java b/android/guava/src/com/google/common/base/Utf8.java index 8a2fbb743cf3..bb945a35f095 100644 --- a/android/guava/src/com/google/common/base/Utf8.java +++ b/android/guava/src/com/google/common/base/Utf8.java @@ -38,6 +38,7 @@ */ @Beta @GwtCompatible(emulated = true) +@ElementTypesAreNonnullByDefault public final class Utf8 { /** * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string, this diff --git a/android/guava/src/com/google/common/base/Verify.java b/android/guava/src/com/google/common/base/Verify.java index 843a77fe91f0..b2e9f5f04faf 100644 --- a/android/guava/src/com/google/common/base/Verify.java +++ b/android/guava/src/com/google/common/base/Verify.java @@ -18,7 +18,8 @@ import com.google.common.annotations.GwtCompatible; import com.google.errorprone.annotations.CanIgnoreReturnValue; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Static convenience methods that serve the same purpose as Java language T verifyNotNull(@NullableDecl T reference) { + public static T verifyNotNull(@CheckForNull T reference) { return verifyNotNull(reference, "expected a non-null reference"); } @@ -514,10 +496,12 @@ public static T verifyNotNull(@NullableDecl T reference) { */ @CanIgnoreReturnValue public static T verifyNotNull( - @NullableDecl T reference, - @NullableDecl String errorMessageTemplate, - @NullableDecl Object... errorMessageArgs) { - verify(reference != null, errorMessageTemplate, errorMessageArgs); + @CheckForNull T reference, + String errorMessageTemplate, + @CheckForNull @Nullable Object... errorMessageArgs) { + if (reference == null) { + throw new VerifyException(lenientFormat(errorMessageTemplate, errorMessageArgs)); + } return reference; } diff --git a/android/guava/src/com/google/common/base/VerifyException.java b/android/guava/src/com/google/common/base/VerifyException.java index eed5c6df2996..10b99dee722b 100644 --- a/android/guava/src/com/google/common/base/VerifyException.java +++ b/android/guava/src/com/google/common/base/VerifyException.java @@ -15,7 +15,7 @@ package com.google.common.base; import com.google.common.annotations.GwtCompatible; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * Exception thrown upon the failure of a bigThreadConstructor = getBigThreadConstructor(); - @NullableDecl + @CheckForNull private static final Field inheritableThreadLocals = (bigThreadConstructor == null) ? getInheritableThreadLocalsField() : null; @@ -130,8 +131,7 @@ private Finalizer( PhantomReference frqReference) { this.queue = queue; - this.finalizableReferenceClassReference = - new WeakReference>(finalizableReferenceClass); + this.finalizableReferenceClassReference = new WeakReference<>(finalizableReferenceClass); // Keep track of the FRQ that started us so we know when to stop. this.frqReference = frqReference; @@ -192,7 +192,7 @@ private boolean cleanUp(Reference reference) { } /** Looks up FinalizableReference.finalizeReferent() method. */ - @NullableDecl + @CheckForNull private Method getFinalizeReferentMethod() { Class finalizableReferenceClass = finalizableReferenceClassReference.get(); if (finalizableReferenceClass == null) { @@ -211,7 +211,7 @@ private Method getFinalizeReferentMethod() { } } - @NullableDecl + @CheckForNull private static Field getInheritableThreadLocalsField() { try { Field inheritableThreadLocals = Thread.class.getDeclaredField("inheritableThreadLocals"); @@ -226,7 +226,7 @@ private static Field getInheritableThreadLocalsField() { } } - @NullableDecl + @CheckForNull private static Constructor getBigThreadConstructor() { try { return Thread.class.getConstructor( diff --git a/android/guava/src/com/google/common/cache/AbstractCache.java b/android/guava/src/com/google/common/cache/AbstractCache.java index d8ef0323a81d..eec5fdc34f56 100644 --- a/android/guava/src/com/google/common/cache/AbstractCache.java +++ b/android/guava/src/com/google/common/cache/AbstractCache.java @@ -38,6 +38,7 @@ * @since 10.0 */ @GwtCompatible +@ElementTypesAreNonnullByDefault public abstract class AbstractCache implements Cache { /** Constructor for use by subclasses. */ @@ -58,8 +59,12 @@ public V get(K key, Callable valueLoader) throws ExecutionException * * @since 11.0 */ + /* + * is mostly the same as to plain Java. But to nullness checkers, they + * differ: means "non-null types," while means "all types." + */ @Override - public ImmutableMap getAllPresent(Iterable keys) { + public ImmutableMap getAllPresent(Iterable keys) { Map result = Maps.newLinkedHashMap(); for (Object key : keys) { if (!result.containsKey(key)) { @@ -103,7 +108,8 @@ public void invalidate(Object key) { /** @since 11.0 */ @Override - public void invalidateAll(Iterable keys) { + // For discussion of , see getAllPresent. + public void invalidateAll(Iterable keys) { for (Object key : keys) { invalidate(key); } diff --git a/android/guava/src/com/google/common/cache/AbstractLoadingCache.java b/android/guava/src/com/google/common/cache/AbstractLoadingCache.java index 38b97747915e..489597c51843 100644 --- a/android/guava/src/com/google/common/cache/AbstractLoadingCache.java +++ b/android/guava/src/com/google/common/cache/AbstractLoadingCache.java @@ -38,6 +38,7 @@ * @since 11.0 */ @GwtIncompatible +@ElementTypesAreNonnullByDefault public abstract class AbstractLoadingCache extends AbstractCache implements LoadingCache { diff --git a/android/guava/src/com/google/common/cache/Cache.java b/android/guava/src/com/google/common/cache/Cache.java index a47c4fe47b3e..1234bb6a3e96 100644 --- a/android/guava/src/com/google/common/cache/Cache.java +++ b/android/guava/src/com/google/common/cache/Cache.java @@ -25,7 +25,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import javax.annotation.CheckForNull; /** * A semi-persistent mapping from keys to values. Cache entries are manually added using {@link @@ -35,11 +35,14 @@ *

    Implementations of this interface are expected to be thread-safe, and can be safely accessed * by multiple concurrent threads. * + * @param the type of the cache's keys, which are not permitted to be null + * @param the type of the cache's values, which are not permitted to be null * @author Charles Fry * @since 10.0 */ @DoNotMock("Use CacheBuilder.newBuilder().build()") @GwtCompatible +@ElementTypesAreNonnullByDefault public interface Cache { /** @@ -48,7 +51,7 @@ public interface Cache { * * @since 11.0 */ - @NullableDecl + @CheckForNull V getIfPresent(@CompatibleWith("K") Object key); /** @@ -105,7 +108,11 @@ public interface Cache { * * @since 11.0 */ - ImmutableMap getAllPresent(Iterable keys); + /* + * is mostly the same as to plain Java. But to nullness checkers, they + * differ: means "non-null types," while means "all types." + */ + ImmutableMap getAllPresent(Iterable keys); /** * Associates {@code value} with {@code key} in this cache. If the cache previously contained a @@ -136,7 +143,8 @@ public interface Cache { * * @since 11.0 */ - void invalidateAll(Iterable keys); + // For discussion of , see getAllPresent. + void invalidateAll(Iterable keys); /** Discards all entries in the cache. */ void invalidateAll(); diff --git a/android/guava/src/com/google/common/cache/CacheBuilder.java b/android/guava/src/com/google/common/cache/CacheBuilder.java index c46779b5a926..b690973b2505 100644 --- a/android/guava/src/com/google/common/cache/CacheBuilder.java +++ b/android/guava/src/com/google/common/cache/CacheBuilder.java @@ -39,15 +39,57 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import org.checkerframework.checker.nullness.qual.Nullable; /** - * A builder of {@link LoadingCache} and {@link Cache} instances having any combination of the - * following features: + * A builder of {@link LoadingCache} and {@link Cache} instances. + * + *

    Prefer Caffeine over Guava's caching + * API

    + * + *

    The successor to Guava's caching API is Caffeine. Its API is designed to make it a + * nearly drop-in replacement -- though it requires Java 8 APIs, is not available for Android or + * GWT/j2cl, and may have different + * (usually better) behavior when multiple threads attempt concurrent mutations. Its equivalent + * to {@code CacheBuilder} is its {@code + * Caffeine} class. Caffeine offers better performance, more features (including asynchronous + * loading), and fewer bugs. + * + *

    Caffeine defines its own interfaces ({@code + * Cache}, {@code + * LoadingCache}, {@code + * CacheLoader}, etc.), so you can use Caffeine without needing to use any Guava types. + * Caffeine's types are better than Guava's, especially for their + * deep support for asynchronous operations. But if you want to migrate to Caffeine with minimal + * code changes, you can use its + * {@code CaffeinatedGuava} adapter class, which lets you build a Guava {@code Cache} or a Guava + * {@code LoadingCache} backed by a Guava {@code CacheLoader}. + * + *

    Caffeine's API for asynchronous operations uses {@code CompletableFuture}: {@code + * AsyncLoadingCache.get} returns a {@code CompletableFuture}, and implementations of {@code + * AsyncCacheLoader.asyncLoad} must return a {@code CompletableFuture}. Users of Guava's {@link + * com.google.common.util.concurrent.ListenableFuture} can adapt between the two {@code Future} + * types by using {@code + * net.javacrumbs.futureconverter.java8guava.FutureConverter}. + * + *

    More on {@code CacheBuilder}

    + * + * {@code CacheBuilder} builds caches with any combination of the following features: * *