Skip to content

Commit

Permalink
migrate to jspecify annotations (was checker framework)
Browse files Browse the repository at this point in the history
All packages are annotated with `NullMarked` to make it the default
behavior. The user-facing classes are explicitly annotated as
documentation to convey intent to the reader.
  • Loading branch information
ben-manes committed Nov 26, 2024
1 parent a31defd commit 40c5022
Show file tree
Hide file tree
Showing 228 changed files with 663 additions and 326 deletions.
3 changes: 2 additions & 1 deletion caffeine/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ val javaPoetRuntimeOnly: Configuration = configurations["javaPoetRuntimeOnly"]
val javaPoetImplementation: Configuration = configurations["javaPoetImplementation"]

dependencies {
api(libs.checker.annotations)
api(libs.jspecify)
api(libs.errorprone.annotations)

testImplementation(libs.joor)
Expand Down Expand Up @@ -75,6 +75,7 @@ dependencies {

javaPoetImplementation(libs.guava)
javaPoetImplementation(libs.javapoet)
javaPoetImplementation(libs.jspecify)
javaPoetImplementation(libs.commons.lang3)

javaPoetRuntimeOnly(libs.google.java.format)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.ParameterSpec;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@NullMarked
@CheckReturnValue
package com.github.benmanes.caffeine.cache.local;

import org.jspecify.annotations.NullMarked;

import com.google.errorprone.annotations.CheckReturnValue;
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@NullMarked
@CheckReturnValue
package com.github.benmanes.caffeine.cache.node;

import org.jspecify.annotations.NullMarked;

import com.google.errorprone.annotations.CheckReturnValue;
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@NullMarked
@CheckReturnValue
package com.github.benmanes.caffeine.cache;

import org.jspecify.annotations.NullMarked;

import com.google.errorprone.annotations.CheckReturnValue;
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
package com.github.benmanes.caffeine.cache;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

/**
* A facade for benchmark implementations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@NullMarked
@CheckReturnValue
package com.github.benmanes.caffeine.cache.impl;

import org.jspecify.annotations.NullMarked;

import com.google.errorprone.annotations.CheckReturnValue;
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@NullMarked
@CheckReturnValue
package com.github.benmanes.caffeine.cache;

import org.jspecify.annotations.NullMarked;

import com.google.errorprone.annotations.CheckReturnValue;
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

import static com.google.common.base.Preconditions.checkArgument;

import org.checkerframework.checker.index.qual.NonNegative;

import com.google.common.math.IntMath;

/**
Expand Down Expand Up @@ -77,7 +75,7 @@ public CountMinSketch() {}
*
* @param maximumSize the maximum size of the cache
*/
public void ensureCapacity(@NonNegative long maximumSize) {
public void ensureCapacity(long maximumSize) {
checkArgument(maximumSize >= 0);
int maximum = (int) Math.min(maximumSize, Integer.MAX_VALUE >>> 1);
if ((table != null) && (table.length >= maximum)) {
Expand Down Expand Up @@ -107,7 +105,7 @@ public boolean isNotInitialized() {
* @param e the element to count occurrences of
* @return the estimated number of occurrences of the element; possibly zero but never negative
*/
public @NonNegative int frequency(E e) {
public int frequency(E e) {
if (isNotInitialized()) {
return 0;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@NullMarked
@CheckReturnValue
package com.github.benmanes.caffeine.cache.sketch;

import org.jspecify.annotations.NullMarked;

import com.google.errorprone.annotations.CheckReturnValue;
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@NullMarked
@CheckReturnValue
package com.github.benmanes.caffeine;

import org.jspecify.annotations.NullMarked;

import com.google.errorprone.annotations.CheckReturnValue;
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@NullMarked
@CheckReturnValue
package com.github.benmanes.caffeine.profiler;

import org.jspecify.annotations.NullMarked;

import com.google.errorprone.annotations.CheckReturnValue;
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import java.util.ConcurrentModificationException;
import java.util.NoSuchElementException;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

import com.google.errorprone.annotations.Var;

Expand Down Expand Up @@ -192,12 +192,12 @@ public void clear() {
public abstract boolean contains(Object o);

@Override
public boolean isFirst(E e) {
public boolean isFirst(@Nullable E e) {
return (e != null) && (e == first);
}

@Override
public boolean isLast(E e) {
public boolean isLast(@Nullable E e) {
return (e != null) && (e == last);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import java.util.Deque;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

import com.github.benmanes.caffeine.cache.AccessOrderDeque.AccessOrder;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import java.util.concurrent.CompletionException;
import java.util.concurrent.Executor;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

/**
* Static utility methods and classes pertaining to asynchronous operations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
import java.util.function.BiFunction;
import java.util.function.Function;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

/**
* A semi-persistent mapping from keys to values. Cache entries are manually added using
Expand All @@ -37,6 +38,7 @@
* @param <K> the type of keys maintained by this cache
* @param <V> the type of mapped values
*/
@NullMarked
public interface AsyncCache<K, V> {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import java.util.function.BiFunction;
import java.util.function.Function;

import org.jspecify.annotations.NullMarked;

/**
* Computes or retrieves values asynchronously based on a key, for use in populating a
* {@link AsyncLoadingCache}.
Expand All @@ -42,6 +44,7 @@
* @param <V> the type of values
* @author [email protected] (Ben Manes)
*/
@NullMarked
@FunctionalInterface
@SuppressWarnings("PMD.SignatureDeclareThrowsException")
public interface AsyncCacheLoader<K, V> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import org.jspecify.annotations.NullMarked;

/**
* A semi-persistent mapping from keys to values. Values are automatically loaded by the cache
* asynchronously and are stored in the cache until either evicted or manually invalidated.
Expand All @@ -29,6 +31,7 @@
* @param <K> the type of keys maintained by this cache
* @param <V> the type of mapped values
*/
@NullMarked
public interface AsyncLoadingCache<K, V> extends AsyncCache<K, V> {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

import com.github.benmanes.caffeine.cache.Async.AsyncExpiry;
import com.github.benmanes.caffeine.cache.LinkedDeque.PeekingIterator;
Expand Down Expand Up @@ -1756,7 +1756,7 @@ void drainValueReferences() {
}
@Var Reference<? extends V> valueRef;
while ((valueRef = valueReferenceQueue().poll()) != null) {
@SuppressWarnings("unchecked")
@SuppressWarnings({"RedundantCast", "unchecked"})
var ref = (InternalReference<V>) (Object) valueRef;
Node<K, V> node = data.get(ref.getKeyReference());
if ((node != null) && (valueRef == node.getValueReference())) {
Expand Down Expand Up @@ -3011,7 +3011,7 @@ public Set<Entry<K, V>> entrySet() {
* {@link #size()} as many usages assume it to be instantaneous and lock-free.
*/
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Map)) {
Expand Down Expand Up @@ -3090,7 +3090,7 @@ public String toString() {
* @return the computed value
*/
@SuppressWarnings("GuardedByChecker")
<T> T evictionOrder(boolean hottest, Function<V, V> transformer,
<T> T evictionOrder(boolean hottest, Function<@Nullable V, @Nullable V> transformer,
Function<Stream<CacheEntry<K, V>>, T> mappingFunction) {
Comparator<Node<K, V>> comparator = Comparator.comparingInt(node -> {
K key = node.getKey();
Expand Down Expand Up @@ -3125,7 +3125,7 @@ <T> T evictionOrder(boolean hottest, Function<V, V> transformer,
* @return the computed value
*/
@SuppressWarnings("GuardedByChecker")
<T> T expireAfterAccessOrder(boolean oldest, Function<V, V> transformer,
<T> T expireAfterAccessOrder(boolean oldest, Function<@Nullable V, @Nullable V> transformer,
Function<Stream<CacheEntry<K, V>>, T> mappingFunction) {
Iterable<Node<K, V>> iterable;
if (evicts()) {
Expand Down Expand Up @@ -3163,7 +3163,7 @@ <T> T expireAfterAccessOrder(boolean oldest, Function<V, V> transformer,
* @param mappingFunction the mapping function to compute a value
* @return the computed value
*/
<T> T snapshot(Iterable<Node<K, V>> iterable, Function<V, V> transformer,
<T> T snapshot(Iterable<Node<K, V>> iterable, Function<@Nullable V, @Nullable V> transformer,
Function<Stream<CacheEntry<K, V>>, T> mappingFunction) {
requireNonNull(mappingFunction);
requireNonNull(transformer);
Expand Down Expand Up @@ -3865,7 +3865,7 @@ public int characteristics() {
}

/** A reusable task that performs the maintenance work; used to avoid wrapping by ForkJoinPool. */
static final class PerformCleanupTask extends ForkJoinTask<Void> implements Runnable {
static final class PerformCleanupTask extends ForkJoinTask<@Nullable Void> implements Runnable {
private static final long serialVersionUID = 1L;

final WeakReference<BoundedLocalCache<?, ?>> reference;
Expand Down Expand Up @@ -3901,10 +3901,10 @@ public void run() {
*/
// public final void quietlyComplete() {}

@Override public Void getRawResult() { return null; }
@Override public void setRawResult(Void v) {}
@Override public void complete(Void value) {}
@Override public void setRawResult(@Nullable Void v) {}
@Override public void complete(@Nullable Void value) {}
@Override public void completeExceptionally(Throwable ex) {}
@Override public @Nullable Void getRawResult() { return null; }
@Override public boolean cancel(boolean mayInterruptIfRunning) { return false; }
}

Expand Down Expand Up @@ -3967,8 +3967,12 @@ public BoundedLocalCache<K, V> cache() {

@Override
public Policy<K, V> policy() {
var p = policy;
return (p == null) ? (policy = new BoundedPolicy<>(cache, identity(), cache.isWeighted)) : p;
if (policy == null) {
@SuppressWarnings("NullAway")
Function<@Nullable V, @Nullable V> identity = identity();
policy = new BoundedPolicy<>(cache, identity, cache.isWeighted);
}
return policy;
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
Expand Down Expand Up @@ -4527,8 +4531,8 @@ public Policy<K, V> policy() {
@SuppressWarnings("unchecked")
var castCache = (BoundedLocalCache<K, V>) cache;
Function<CompletableFuture<V>, @Nullable V> transformer = Async::getIfReady;
@SuppressWarnings("unchecked")
var castTransformer = (Function<V, V>) transformer;
@SuppressWarnings({"NullAway", "unchecked", "Varifier"})
Function<@Nullable V, @Nullable V> castTransformer = (Function<V, V>) transformer;
policy = new BoundedPolicy<>(castCache, castTransformer, isWeighted);
}
return policy;
Expand Down Expand Up @@ -4579,8 +4583,8 @@ public Policy<K, V> policy() {
@SuppressWarnings("unchecked")
var castCache = (BoundedLocalCache<K, V>) cache;
Function<CompletableFuture<V>, @Nullable V> transformer = Async::getIfReady;
@SuppressWarnings("unchecked")
var castTransformer = (Function<V, V>) transformer;
@SuppressWarnings({"NullAway", "unchecked", "Varifier"})
Function<@Nullable V, @Nullable V> castTransformer = (Function<V, V>) transformer;
policy = new BoundedPolicy<>(castCache, castTransformer, isWeighted);
}
return policy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;

import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.PolyNull;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

import com.github.benmanes.caffeine.cache.stats.CacheStats;

Expand All @@ -38,6 +37,7 @@
* @param <K> the type of keys maintained by this cache
* @param <V> the type of mapped values
*/
@NullMarked
public interface Cache<K, V> {

/**
Expand Down Expand Up @@ -77,8 +77,7 @@ public interface Cache<K, V> {
* @throws RuntimeException or Error if the mappingFunction does so, in which case the mapping is
* left unestablished
*/
@PolyNull
V get(K key, Function<? super K, ? extends @PolyNull V> mappingFunction);
V get(K key, Function<? super K, ? extends V> mappingFunction);

/**
* Returns a map of the values associated with the {@code keys} in this cache. The returned map
Expand Down Expand Up @@ -180,7 +179,6 @@ Map<K, V> getAll(Iterable<? extends K> keys,
*
* @return the estimated number of mappings
*/
@NonNegative
long estimatedSize();

/**
Expand Down
Loading

0 comments on commit 40c5022

Please sign in to comment.