From c87cac1ccf9301f42a25d14d0d69d2a12cedd7fb Mon Sep 17 00:00:00 2001 From: Sparky <87631423+Sparky983@users.noreply.github.com> Date: Sun, 17 Mar 2024 15:24:51 +1100 Subject: [PATCH 1/3] Replace internal `@Nullable` with JSpecify `@Nullable` --- gradle/libs.versions.toml | 1 + helios/build.gradle.kts | 2 ++ .../main/java/me/sparky983/helios/Absent.java | 8 +++---- .../java/me/sparky983/helios/Optional.java | 16 ++++++------- .../java/me/sparky983/helios/Present.java | 6 ++--- .../helios/annotations/Nullable.java | 23 ------------------- helios/src/main/java/module-info.java | 1 + 7 files changed, 19 insertions(+), 38 deletions(-) delete mode 100644 helios/src/main/java/me/sparky983/helios/annotations/Nullable.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f9305a9..a82ee0e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,6 +2,7 @@ junit = "5.10.0" [libraries] +jspecify-annotations = { group = "org.jspecify", name = "jspecify", version = "0.3.0" } junit-jupiter-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit" } junit-jupiter-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junit" } junit-jupiter-params = { group = "org.junit.jupiter", name = "junit-jupiter-params", version.ref = "junit" } diff --git a/helios/build.gradle.kts b/helios/build.gradle.kts index f6cbcbe..0c959a4 100644 --- a/helios/build.gradle.kts +++ b/helios/build.gradle.kts @@ -6,6 +6,8 @@ plugins { } dependencies { + compileOnly(libs.jspecify.annotations) + testImplementation(libs.junit.jupiter.api) testImplementation(libs.junit.jupiter.params) testRuntimeOnly(libs.junit.jupiter.engine) diff --git a/helios/src/main/java/me/sparky983/helios/Absent.java b/helios/src/main/java/me/sparky983/helios/Absent.java index 4a1057b..cdde616 100644 --- a/helios/src/main/java/me/sparky983/helios/Absent.java +++ b/helios/src/main/java/me/sparky983/helios/Absent.java @@ -5,7 +5,7 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; -import me.sparky983.helios.annotations.Nullable; +import org.jspecify.annotations.Nullable; /** * An {@code Optional} that contains no value. @@ -14,7 +14,7 @@ * @since 0.1.0 * @helios.apiNote This class should not be constructed directly. Use {@link #absent()} instead. */ -public record Absent() implements Optional { +public record Absent() implements Optional { static final Absent ABSENT = new Absent<>(); @Override @@ -85,14 +85,14 @@ public T expect(final String message) { } @Override - public Optional map(final Function mapper) { + public Optional map(final Function mapper) { Objects.requireNonNull(mapper, "mapper cannot be null"); return Optional.absent(); } @Override - public Optional flatMap( + public Optional flatMap( final Function> mapper) { Objects.requireNonNull(mapper, "mapper cannot be null"); diff --git a/helios/src/main/java/me/sparky983/helios/Optional.java b/helios/src/main/java/me/sparky983/helios/Optional.java index 0507946..e9ffdc0 100644 --- a/helios/src/main/java/me/sparky983/helios/Optional.java +++ b/helios/src/main/java/me/sparky983/helios/Optional.java @@ -5,7 +5,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; import me.sparky983.helios.annotations.Experimental; -import me.sparky983.helios.annotations.Nullable; +import org.jspecify.annotations.Nullable; /** * An immutable container which may contain a non-null value. @@ -231,7 +231,7 @@ * } * } */ -public sealed interface Optional permits Present, Absent { +public sealed interface Optional permits Present, Absent { /** * Returns a present {@code Optional} containing the given value. * @@ -240,7 +240,7 @@ public sealed interface Optional permits Present, Absent { * @param the type of the value * @throws NullPointerException if the value is {@code null}. */ - static Optional present(final T value) { + static Optional present(final T value) { return new Present<>(value); } @@ -254,7 +254,7 @@ static Optional present(final T value) { * @helios.implNote This method returns a singleton instance of {@link Absent}. */ @SuppressWarnings("unchecked") - static Optional absent() { + static Optional absent() { return (Absent) Absent.ABSENT; } @@ -275,7 +275,7 @@ static Optional absent() { * Optional optional = Optional.fromNullable(map.get("key")); * } */ - static Optional fromNullable(final @Nullable T value) { + static Optional fromNullable(final @Nullable T value) { if (value != null) { return present(value); } else { @@ -303,7 +303,7 @@ static Optional fromNullable(final @Nullable T value) { * } */ @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - static Optional from(final java.util.Optional optional) { + static Optional from(final java.util.Optional optional) { return optional.map(Optional::present).orElse(Optional.absent()); } @@ -485,7 +485,7 @@ static Optional from(final java.util.Optional optional) * assert absent.map(n -> n * 2).isAbsent(); * } */ - Optional map(Function mapper); + Optional map(Function mapper); /** * If this {@code Optional} is present, returns the result of applying the given mapper to the @@ -508,7 +508,7 @@ static Optional from(final java.util.Optional optional) * .flatMap(user -> user.findRepository("helios")); * } */ - Optional flatMap( + Optional flatMap( Function> mapper); /** diff --git a/helios/src/main/java/me/sparky983/helios/Present.java b/helios/src/main/java/me/sparky983/helios/Present.java index 6d72faa..fea7f81 100644 --- a/helios/src/main/java/me/sparky983/helios/Present.java +++ b/helios/src/main/java/me/sparky983/helios/Present.java @@ -14,7 +14,7 @@ * @helios.apiNote This class should not be constructed directly and is only public for pattern * matching. Use {@link #present(Object)} instead. */ -public record Present(T value) implements Optional { +public record Present(T value) implements Optional { /** * Constructs a new {@code Present} {@code Optional} with the given value. * @@ -83,7 +83,7 @@ public T expect(final String message) { } @Override - public Optional map(final Function mapper) { + public Optional map(final Function mapper) { Objects.requireNonNull(mapper, "mapper cannot be null"); final var mappedValue = @@ -94,7 +94,7 @@ public Optional map(final Function @SuppressWarnings("unchecked") @Override - public Optional flatMap( + public Optional flatMap( final Function> mapper) { Objects.requireNonNull(mapper, "mapper cannot be null"); diff --git a/helios/src/main/java/me/sparky983/helios/annotations/Nullable.java b/helios/src/main/java/me/sparky983/helios/annotations/Nullable.java deleted file mode 100644 index 947dc3d..0000000 --- a/helios/src/main/java/me/sparky983/helios/annotations/Nullable.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.sparky983.helios.annotations; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Indicates that the annotated type is may contain {@code null}. - *

JSpecify

- * This annotation generally has the same meaning as {@code org.jspecify.annotations.Nullable} - * in JSpecify 0.3, however, it is not well-defined as the meaning may change as JSpecify evolves. - * Additionally, this entire module (me.sparky983.helios) is considered to be in a null-marked - * scope. - * - *

This annotation is also temporary, and will be replaced with - * {@code org.jspecify.annotations.Nullable} once is fully released. - */ -@Documented -@Retention(RetentionPolicy.CLASS) -@Target(ElementType.TYPE_USE) -public @interface Nullable {} diff --git a/helios/src/main/java/module-info.java b/helios/src/main/java/module-info.java index 82e34b0..7456f95 100644 --- a/helios/src/main/java/module-info.java +++ b/helios/src/main/java/module-info.java @@ -10,6 +10,7 @@ @Experimental // 0.x.y module me.sparky983.helios { requires static java.compiler; // for Javadocs + requires static org.jspecify; exports me.sparky983.helios; } From 015fed02b3dedffcf30c4fd9a29d8a7f4872546b Mon Sep 17 00:00:00 2001 From: Sparky983 <87631423+Sparky983@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:46:22 +1000 Subject: [PATCH 2/3] Update to JSpecify 1.0.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a82ee0e..53b77e6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ junit = "5.10.0" [libraries] -jspecify-annotations = { group = "org.jspecify", name = "jspecify", version = "0.3.0" } +jspecify-annotations = { group = "org.jspecify", name = "jspecify", version = "1.0.0" } junit-jupiter-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit" } junit-jupiter-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junit" } junit-jupiter-params = { group = "org.junit.jupiter", name = "junit-jupiter-params", version.ref = "junit" } From 8c6d7dd0e9cb6178e22a34d657123c1851149a72 Mon Sep 17 00:00:00 2001 From: Sparky983 <87631423+Sparky983@users.noreply.github.com> Date: Sat, 10 Aug 2024 13:12:40 +1000 Subject: [PATCH 3/3] Apply Spotless --- helios/src/main/java/me/sparky983/helios/Optional.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/helios/src/main/java/me/sparky983/helios/Optional.java b/helios/src/main/java/me/sparky983/helios/Optional.java index e9ffdc0..d7803ce 100644 --- a/helios/src/main/java/me/sparky983/helios/Optional.java +++ b/helios/src/main/java/me/sparky983/helios/Optional.java @@ -508,8 +508,7 @@ static Optional from(final java.util.Optional optional) { * .flatMap(user -> user.findRepository("helios")); * } */ - Optional flatMap( - Function> mapper); + Optional flatMap(Function> mapper); /** * If this {@code Optional} is present and the value matches the given predicate, returns this