Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add @CanIgnoreReturnValue annotations #868

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import com.github.benmanes.caffeine.cache.stats.CacheStats;
import com.github.benmanes.caffeine.cache.stats.ConcurrentStatsCounter;
import com.github.benmanes.caffeine.cache.stats.StatsCounter;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.FormatMethod;

/**
Expand Down Expand Up @@ -291,6 +292,7 @@ public static Caffeine<Object, Object> from(String spec) {
* @throws IllegalArgumentException if {@code initialCapacity} is negative
* @throws IllegalStateException if an initial capacity was already set
*/
@CanIgnoreReturnValue
public Caffeine<K, V> initialCapacity(@NonNegative int initialCapacity) {
requireState(this.initialCapacity == UNSET_INT,
"initial capacity was already set to %s", this.initialCapacity);
Expand Down Expand Up @@ -324,6 +326,7 @@ int getInitialCapacity() {
* @return this {@code Caffeine} instance (for chaining)
* @throws NullPointerException if the specified executor is null
*/
@CanIgnoreReturnValue
public Caffeine<K, V> executor(Executor executor) {
requireState(this.executor == null, "executor was already set to %s", this.executor);
this.executor = requireNonNull(executor);
Expand Down Expand Up @@ -355,6 +358,7 @@ Executor getExecutor() {
* @return this {@code Caffeine} instance (for chaining)
* @throws NullPointerException if the specified scheduler is null
*/
@CanIgnoreReturnValue
public Caffeine<K, V> scheduler(Scheduler scheduler) {
requireState(this.scheduler == null, "scheduler was already set to %s", this.scheduler);
this.scheduler = requireNonNull(scheduler);
Expand Down Expand Up @@ -389,6 +393,7 @@ Scheduler getScheduler() {
* @throws IllegalArgumentException if {@code size} is negative
* @throws IllegalStateException if a maximum size or weight was already set
*/
@CanIgnoreReturnValue
public Caffeine<K, V> maximumSize(@NonNegative long maximumSize) {
requireState(this.maximumSize == UNSET_INT,
"maximum size was already set to %s", this.maximumSize);
Expand Down Expand Up @@ -425,6 +430,7 @@ public Caffeine<K, V> maximumSize(@NonNegative long maximumSize) {
* @throws IllegalArgumentException if {@code maximumWeight} is negative
* @throws IllegalStateException if a maximum weight or size was already set
*/
@CanIgnoreReturnValue
public Caffeine<K, V> maximumWeight(@NonNegative long maximumWeight) {
requireState(this.maximumWeight == UNSET_INT,
"maximum weight was already set to %s", this.maximumWeight);
Expand Down Expand Up @@ -465,6 +471,7 @@ public Caffeine<K, V> maximumWeight(@NonNegative long maximumWeight) {
* remaining configuration and cache building
* @throws IllegalStateException if a weigher was already set
*/
@CanIgnoreReturnValue
public <K1 extends K, V1 extends V> Caffeine<K1, V1> weigher(
Weigher<? super K1, ? super V1> weigher) {
requireNonNull(weigher);
Expand Down Expand Up @@ -517,6 +524,7 @@ <K1 extends K, V1 extends V> Weigher<K1, V1> getWeigher(boolean isAsync) {
* @return this {@code Caffeine} instance (for chaining)
* @throws IllegalStateException if the key strength was already set
*/
@CanIgnoreReturnValue
public Caffeine<K, V> weakKeys() {
requireState(keyStrength == null, "Key strength was already set to %s", keyStrength);
keyStrength = Strength.WEAK;
Expand Down Expand Up @@ -546,6 +554,7 @@ boolean isStrongKeys() {
* @return this {@code Caffeine} instance (for chaining)
* @throws IllegalStateException if the value strength was already set
*/
@CanIgnoreReturnValue
public Caffeine<K, V> weakValues() {
requireState(valueStrength == null, "Value strength was already set to %s", valueStrength);
valueStrength = Strength.WEAK;
Expand Down Expand Up @@ -582,6 +591,7 @@ boolean isWeakValues() {
* @return this {@code Caffeine} instance (for chaining)
* @throws IllegalStateException if the value strength was already set
*/
@CanIgnoreReturnValue
public Caffeine<K, V> softValues() {
requireState(valueStrength == null, "Value strength was already set to %s", valueStrength);
valueStrength = Strength.SOFT;
Expand All @@ -604,6 +614,7 @@ public Caffeine<K, V> softValues() {
* @throws IllegalStateException if the time to live or variable expiration was already set
* @throws ArithmeticException for durations greater than +/- approximately 292 years
*/
@CanIgnoreReturnValue
public Caffeine<K, V> expireAfterWrite(Duration duration) {
return expireAfterWrite(saturatedToNanos(duration), TimeUnit.NANOSECONDS);
}
Expand All @@ -627,6 +638,7 @@ public Caffeine<K, V> expireAfterWrite(Duration duration) {
* @throws IllegalArgumentException if {@code duration} is negative
* @throws IllegalStateException if the time to live or variable expiration was already set
*/
@CanIgnoreReturnValue
public Caffeine<K, V> expireAfterWrite(@NonNegative long duration, TimeUnit unit) {
requireState(expireAfterWriteNanos == UNSET_INT,
"expireAfterWrite was already set to %s ns", expireAfterWriteNanos);
Expand Down Expand Up @@ -663,6 +675,7 @@ boolean expiresAfterWrite() {
* @throws IllegalStateException if the time to idle or variable expiration was already set
* @throws ArithmeticException for durations greater than +/- approximately 292 years
*/
@CanIgnoreReturnValue
public Caffeine<K, V> expireAfterAccess(Duration duration) {
return expireAfterAccess(saturatedToNanos(duration), TimeUnit.NANOSECONDS);
}
Expand All @@ -689,6 +702,7 @@ public Caffeine<K, V> expireAfterAccess(Duration duration) {
* @throws IllegalArgumentException if {@code duration} is negative
* @throws IllegalStateException if the time to idle or variable expiration was already set
*/
@CanIgnoreReturnValue
public Caffeine<K, V> expireAfterAccess(@NonNegative long duration, TimeUnit unit) {
requireState(expireAfterAccessNanos == UNSET_INT,
"expireAfterAccess was already set to %s ns", expireAfterAccessNanos);
Expand Down Expand Up @@ -733,6 +747,7 @@ boolean expiresAfterAccess() {
* @return this {@code Caffeine} instance (for chaining)
* @throws IllegalStateException if expiration was already set
*/
@CanIgnoreReturnValue
public <K1 extends K, V1 extends V> Caffeine<K1, V1> expireAfter(
Expiry<? super K1, ? super V1> expiry) {
requireNonNull(expiry);
Expand Down Expand Up @@ -779,6 +794,7 @@ boolean expiresVariable() {
* @throws IllegalStateException if the refresh interval was already set
* @throws ArithmeticException for durations greater than +/- approximately 292 years
*/
@CanIgnoreReturnValue
public Caffeine<K, V> refreshAfterWrite(Duration duration) {
return refreshAfterWrite(saturatedToNanos(duration), TimeUnit.NANOSECONDS);
}
Expand Down Expand Up @@ -806,6 +822,7 @@ public Caffeine<K, V> refreshAfterWrite(Duration duration) {
* @throws IllegalArgumentException if {@code duration} is zero or negative
* @throws IllegalStateException if the refresh interval was already set
*/
@CanIgnoreReturnValue
public Caffeine<K, V> refreshAfterWrite(@NonNegative long duration, TimeUnit unit) {
requireNonNull(unit);
requireState(refreshAfterWriteNanos == UNSET_INT,
Expand Down Expand Up @@ -835,6 +852,7 @@ boolean refreshAfterWrite() {
* @throws IllegalStateException if a ticker was already set
* @throws NullPointerException if the specified ticker is null
*/
@CanIgnoreReturnValue
public Caffeine<K, V> ticker(Ticker ticker) {
requireState(this.ticker == null, "Ticker was already set to %s", this.ticker);
this.ticker = requireNonNull(ticker);
Expand Down Expand Up @@ -883,6 +901,7 @@ Ticker getTicker() {
* @throws IllegalStateException if a removal listener was already set
* @throws NullPointerException if the specified removal listener is null
*/
@CanIgnoreReturnValue
public <K1 extends K, V1 extends V> Caffeine<K1, V1> evictionListener(
RemovalListener<? super K1, ? super V1> evictionListener) {
requireState(this.evictionListener == null,
Expand Down Expand Up @@ -934,6 +953,7 @@ public <K1 extends K, V1 extends V> Caffeine<K1, V1> evictionListener(
* @throws IllegalStateException if a removal listener was already set
* @throws NullPointerException if the specified removal listener is null
*/
@CanIgnoreReturnValue
public <K1 extends K, V1 extends V> Caffeine<K1, V1> removalListener(
RemovalListener<? super K1, ? super V1> removalListener) {
requireState(this.removalListener == null,
Expand Down Expand Up @@ -961,6 +981,7 @@ public <K1 extends K, V1 extends V> Caffeine<K1, V1> removalListener(
*
* @return this {@code Caffeine} instance (for chaining)
*/
@CanIgnoreReturnValue
public Caffeine<K, V> recordStats() {
requireState(this.statsCounterSupplier == null, "Statistics recording was already set");
statsCounterSupplier = ENABLED_STATS_COUNTER_SUPPLIER;
Expand All @@ -977,6 +998,7 @@ public Caffeine<K, V> recordStats() {
* @param statsCounterSupplier a supplier instance that returns a new {@link StatsCounter}
* @return this {@code Caffeine} instance (for chaining)
*/
@CanIgnoreReturnValue
public Caffeine<K, V> recordStats(Supplier<? extends StatsCounter> statsCounterSupplier) {
requireState(this.statsCounterSupplier == null, "Statistics recording was already set");
requireNonNull(statsCounterSupplier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ public interface Weigher<K, V> {
*/
static <K, V> Weigher<K, V> singletonWeigher() {
@SuppressWarnings("unchecked")
Weigher<K, V> self = (Weigher<K, V>) SingletonWeigher.INSTANCE;
return self;
Weigher<K, V> instance = (Weigher<K, V>) SingletonWeigher.INSTANCE;
return instance;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
*
* @author Adam Winer
*/
@SuppressWarnings({"CheckReturnValue", "PreferJavaTimeOverload"})
@SuppressWarnings("PreferJavaTimeOverload")
public class CaffeineSpecGuavaTest extends TestCase {

public void testParse_empty() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import com.google.common.truth.FailureMetadata;
import com.google.common.truth.StandardSubjectBuilder;
import com.google.common.truth.Subject;
import com.google.errorprone.annotations.CanIgnoreReturnValue;

/**
* Propositions for {@link CacheContext} subjects.
Expand Down Expand Up @@ -219,30 +220,37 @@ private StatsSubject(FailureMetadata metadata, CacheContext context) {
|| (context.executorType() == CacheExecutor.DIRECT);
}

@CanIgnoreReturnValue
public StatsSubject hits(long count) {
return awaitStatistic("hitCount", CacheStats::hitCount, count);
}

@CanIgnoreReturnValue
public StatsSubject misses(long count) {
return awaitStatistic("missCount", CacheStats::missCount, count);
}

@CanIgnoreReturnValue
public StatsSubject evictions(long count) {
return awaitStatistic("evictionCount", CacheStats::evictionCount, count);
}

@CanIgnoreReturnValue
public StatsSubject evictionWeight(long count) {
return awaitStatistic("evictionWeight", CacheStats::evictionWeight, count);
}

@CanIgnoreReturnValue
public StatsSubject success(long count) {
return awaitStatistic("loadSuccessCount", CacheStats::loadSuccessCount, count);
}

@CanIgnoreReturnValue
public StatsSubject failures(long count) {
return awaitStatistic("loadFailureCount", CacheStats::loadFailureCount, count);
}

@CanIgnoreReturnValue
private StatsSubject awaitStatistic(String label,
ToLongFunction<CacheStats> supplier, long expectedValue) {
if (isDirect) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.io.Serializable;

import com.github.benmanes.caffeine.cache.Expiry;
import com.google.errorprone.annotations.CanIgnoreReturnValue;

/**
* A builder for unit test convenience.
Expand All @@ -45,12 +46,14 @@ public static ExpiryBuilder expiringAfterCreate(long nanos) {
}

/** Sets the fixed update expiration time. */
@CanIgnoreReturnValue
public ExpiryBuilder expiringAfterUpdate(long nanos) {
updateNanos = nanos;
return this;
}

/** Sets the fixed read expiration time. */
@CanIgnoreReturnValue
public ExpiryBuilder expiringAfterRead(long nanos) {
readNanos = nanos;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

import io.reactivex.subjects.PublishSubject;

import com.google.errorprone.annotations.CanIgnoreReturnValue;

/**
* This class allows a cache to have "write-behind" semantics. The passed in writeAction will only
* be called every 'bufferTime' time with a Map containing the keys and the values that have been
Expand Down Expand Up @@ -67,18 +69,21 @@ public static final class Builder<K, V> {
* The duration that the calls to the cache should be buffered before calling the
* <code>writeAction</code>.
*/
@CanIgnoreReturnValue
public Builder<K, V> bufferTime(long duration, TimeUnit unit) {
this.bufferTimeNanos = TimeUnit.NANOSECONDS.convert(duration, unit);
return this;
}

/** The callback to perform the writing to the database or repository. */
@CanIgnoreReturnValue
public Builder<K, V> writeAction(Consumer<Map<K, V>> writeAction) {
this.writeAction = requireNonNull(writeAction);
return this;
}

/** The action that decides which value to take in case a key was updated multiple times. */
@CanIgnoreReturnValue
public Builder<K, V> coalesce(BinaryOperator<V> coalescer) {
this.coalescer = requireNonNull(coalescer);
return this;
Expand Down
2 changes: 1 addition & 1 deletion gradle/codeQuality.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ tasks.withType(JavaCompile).configureEach {
'LexicographicalAnnotationListing', 'MissingSummary', 'StaticImport' ]
disabledChecks.each { disable(it) }

def errorChecks = [ 'NullAway' ]
def errorChecks = [ 'CanIgnoreReturnValueSuggester', 'NullAway' ]
errorChecks.each { error(it) }

nullaway {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ExecutionError;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.errorprone.annotations.CanIgnoreReturnValue;

/**
* A Caffeine-backed cache through a Guava facade.
Expand Down Expand Up @@ -240,6 +241,7 @@ static final class CacheLoaderException extends RuntimeException {
CacheLoaderException(Exception e) {
super(e);
}
@CanIgnoreReturnValue
@SuppressWarnings({"lgtm [java/non-sync-override]", "UnsynchronizedOverridesSynchronized"})
@Override public Throwable fillInStackTrace() {
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public V apply(K key) {
}

@Override
@SuppressWarnings({"CheckReturnValue", "FutureReturnValueIgnored"})
@SuppressWarnings("FutureReturnValueIgnored")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We generally have been recommending just capturing into a var unused = ... variable instead of using @SuppressWarnings(...). Up to you tho.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see 36 usages of @SuppressWarnings("FutureReturnValueIgnored"). Happy to make this change, but perhaps this is better done in a separate PR. Will await @ben-manes' verdict :)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer @SuppressWarnings as other linters will flag unused variables (e.g. Eclipse). It's unfortunate as it does expand the suppression to the method instead of statement, but does a better job of avoiding warning spam. I'm open to revisiting to a better scheme separately so as to narrow the scope.

public void refresh(K key) {
cache.refresh(key);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.errorprone.annotations.CanIgnoreReturnValue;

/**
* Helper class for creating {@link CacheBuilder} instances with all combinations of several sets of
* parameters.
*
* @author mike nonemacher
*/
@SuppressWarnings({"CanIgnoreReturnValueSuggester", "CheckReturnValue"})
class CacheBuilderFactory {
// Default values contain only 'null', which means don't call the CacheBuilder method (just give
// the CacheBuilder default).
Expand All @@ -49,42 +49,50 @@ class CacheBuilderFactory {
private Set<Strength> keyStrengths = Sets.newHashSet((Strength) null);
private Set<Strength> valueStrengths = Sets.newHashSet((Strength) null);

@CanIgnoreReturnValue
CacheBuilderFactory withConcurrencyLevels(Set<Integer> concurrencyLevels) {
this.concurrencyLevels = Sets.newLinkedHashSet(concurrencyLevels);
return this;
}

@CanIgnoreReturnValue
CacheBuilderFactory withInitialCapacities(Set<Integer> initialCapacities) {
this.initialCapacities = Sets.newLinkedHashSet(initialCapacities);
return this;
}

@CanIgnoreReturnValue
CacheBuilderFactory withMaximumSizes(Set<Integer> maximumSizes) {
this.maximumSizes = Sets.newLinkedHashSet(maximumSizes);
return this;
}

@CanIgnoreReturnValue
CacheBuilderFactory withExpireAfterWrites(Set<DurationSpec> durations) {
this.expireAfterWrites = Sets.newLinkedHashSet(durations);
return this;
}

@CanIgnoreReturnValue
CacheBuilderFactory withExpireAfterAccesses(Set<DurationSpec> durations) {
this.expireAfterAccesses = Sets.newLinkedHashSet(durations);
return this;
}

@CanIgnoreReturnValue
CacheBuilderFactory withRefreshes(Set<DurationSpec> durations) {
this.refreshes = Sets.newLinkedHashSet(durations);
return this;
}

@CanIgnoreReturnValue
CacheBuilderFactory withKeyStrengths(Set<Strength> keyStrengths) {
this.keyStrengths = Sets.newLinkedHashSet(keyStrengths);
Preconditions.checkArgument(!this.keyStrengths.contains(Strength.SOFT));
return this;
}

@CanIgnoreReturnValue
CacheBuilderFactory withValueStrengths(Set<Strength> valueStrengths) {
this.valueStrengths = Sets.newLinkedHashSet(valueStrengths);
return this;
Expand Down