From c5e0ae60ba1973b567ccef17ed4c06479db1ed4f Mon Sep 17 00:00:00 2001 From: Maciej Kucharczyk Date: Sat, 5 Apr 2025 19:23:51 +0200 Subject: [PATCH 1/7] Specify nullness for nodes --- .../java/graphql/language/AbstractNode.java | 15 +++++++++------ .../java/graphql/language/ArrayValue.java | 11 +++++++---- .../java/graphql/language/BooleanValue.java | 11 +++++++---- src/main/java/graphql/language/EnumValue.java | 13 ++++++++----- .../java/graphql/language/FloatValue.java | 13 ++++++++----- src/main/java/graphql/language/IntValue.java | 13 ++++++++----- src/main/java/graphql/language/Node.java | 4 +++- src/main/java/graphql/language/NullValue.java | 11 +++++++---- .../java/graphql/language/ObjectValue.java | 11 +++++++---- .../java/graphql/language/ScalarValue.java | 2 ++ .../java/graphql/language/StringValue.java | 19 +++++++++++-------- src/main/java/graphql/language/Value.java | 2 ++ .../graphql/language/VariableReference.java | 13 ++++++++----- 13 files changed, 87 insertions(+), 51 deletions(-) diff --git a/src/main/java/graphql/language/AbstractNode.java b/src/main/java/graphql/language/AbstractNode.java index f097c9b491..a1bcc83da8 100644 --- a/src/main/java/graphql/language/AbstractNode.java +++ b/src/main/java/graphql/language/AbstractNode.java @@ -6,6 +6,8 @@ import graphql.Assert; import graphql.PublicApi; import graphql.collect.ImmutableKit; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.List; import java.util.Map; @@ -13,18 +15,19 @@ import static graphql.collect.ImmutableKit.map; @PublicApi +@NullMarked public abstract class AbstractNode implements Node { - private final SourceLocation sourceLocation; + private final @Nullable SourceLocation sourceLocation; private final ImmutableList comments; private final IgnoredChars ignoredChars; private final ImmutableMap additionalData; - public AbstractNode(SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars) { + public AbstractNode(@Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars) { this(sourceLocation, comments, ignoredChars, ImmutableKit.emptyMap()); } - public AbstractNode(SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + public AbstractNode(@Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { Assert.assertNotNull(comments, () -> "comments can't be null"); Assert.assertNotNull(ignoredChars, () -> "ignoredChars can't be null"); Assert.assertNotNull(additionalData, () -> "additionalData can't be null"); @@ -36,7 +39,7 @@ public AbstractNode(SourceLocation sourceLocation, List comments, Ignor } @Override - public SourceLocation getSourceLocation() { + public @Nullable SourceLocation getSourceLocation() { return sourceLocation; } @@ -56,7 +59,7 @@ public Map getAdditionalData() { } @SuppressWarnings("unchecked") - protected V deepCopy(V nullableObj) { + protected V deepCopy(V nullableObj) { if (nullableObj == null) { return null; } @@ -64,7 +67,7 @@ protected V deepCopy(V nullableObj) { } @SuppressWarnings("unchecked") - protected List deepCopy(List list) { + protected @Nullable List deepCopy(@Nullable List list) { if (list == null) { return null; } diff --git a/src/main/java/graphql/language/ArrayValue.java b/src/main/java/graphql/language/ArrayValue.java index 154c8b7746..c4b4ce6858 100644 --- a/src/main/java/graphql/language/ArrayValue.java +++ b/src/main/java/graphql/language/ArrayValue.java @@ -7,6 +7,8 @@ import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; import java.util.List; @@ -19,13 +21,14 @@ import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; @PublicApi +@NullMarked public class ArrayValue extends AbstractNode implements Value { public static final String CHILD_VALUES = "values"; private final ImmutableList values; @Internal - protected ArrayValue(List values, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + protected ArrayValue(List values, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { super(sourceLocation, comments, ignoredChars, additionalData); this.values = ImmutableList.copyOf(values); } @@ -67,7 +70,7 @@ public ArrayValue withNewChildren(NodeChildrenContainer newChildren) { } @Override - public boolean isEqualTo(Node o) { + public boolean isEqualTo(@Nullable Node o) { if (this == o) { return true; } @@ -102,7 +105,7 @@ public ArrayValue transform(Consumer builderConsumer) { } public static final class Builder implements NodeBuilder { - private SourceLocation sourceLocation; + private @Nullable SourceLocation sourceLocation; private ImmutableList values = emptyList(); private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; @@ -119,7 +122,7 @@ private Builder(ArrayValue existing) { this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } - public Builder sourceLocation(SourceLocation sourceLocation) { + public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/BooleanValue.java b/src/main/java/graphql/language/BooleanValue.java index 53e99b05e4..38dc621f4e 100644 --- a/src/main/java/graphql/language/BooleanValue.java +++ b/src/main/java/graphql/language/BooleanValue.java @@ -6,6 +6,8 @@ import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; import java.util.List; @@ -19,12 +21,13 @@ import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; @PublicApi +@NullMarked public class BooleanValue extends AbstractNode implements ScalarValue { private final boolean value; @Internal - protected BooleanValue(boolean value, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + protected BooleanValue(boolean value, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { super(sourceLocation, comments, ignoredChars, additionalData); this.value = value; } @@ -59,7 +62,7 @@ public BooleanValue withNewChildren(NodeChildrenContainer newChildren) { } @Override - public boolean isEqualTo(Node o) { + public boolean isEqualTo(@Nullable Node o) { if (this == o) { return true; } @@ -110,7 +113,7 @@ public BooleanValue transform(Consumer builderConsumer) { } public static final class Builder implements NodeBuilder { - private SourceLocation sourceLocation; + private @Nullable SourceLocation sourceLocation; private boolean value; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; @@ -128,7 +131,7 @@ private Builder(BooleanValue existing) { } - public Builder sourceLocation(SourceLocation sourceLocation) { + public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/EnumValue.java b/src/main/java/graphql/language/EnumValue.java index 999b58712f..fdd03b9604 100644 --- a/src/main/java/graphql/language/EnumValue.java +++ b/src/main/java/graphql/language/EnumValue.java @@ -6,6 +6,8 @@ import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; import java.util.List; @@ -20,12 +22,13 @@ import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; @PublicApi +@NullMarked public class EnumValue extends AbstractNode implements Value, NamedNode { private final String name; @Internal - protected EnumValue(String name, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + protected EnumValue(String name, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; } @@ -67,7 +70,7 @@ public EnumValue withNewChildren(NodeChildrenContainer newChildren) { } @Override - public boolean isEqualTo(Node o) { + public boolean isEqualTo(@Nullable Node o) { if (this == o) { return true; } @@ -112,8 +115,8 @@ public EnumValue transform(Consumer builderConsumer) { } public static final class Builder implements NodeBuilder { - private SourceLocation sourceLocation; - private String name; + private @Nullable SourceLocation sourceLocation; + private @Nullable String name; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -129,7 +132,7 @@ private Builder(EnumValue existing) { } - public Builder sourceLocation(SourceLocation sourceLocation) { + public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/FloatValue.java b/src/main/java/graphql/language/FloatValue.java index 90dd476a84..f3712dbc59 100644 --- a/src/main/java/graphql/language/FloatValue.java +++ b/src/main/java/graphql/language/FloatValue.java @@ -6,6 +6,8 @@ import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.math.BigDecimal; import java.util.LinkedHashMap; @@ -21,12 +23,13 @@ import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; @PublicApi +@NullMarked public class FloatValue extends AbstractNode implements ScalarValue { private final BigDecimal value; @Internal - protected FloatValue(BigDecimal value, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + protected FloatValue(BigDecimal value, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { super(sourceLocation, comments, ignoredChars, additionalData); this.value = value; } @@ -68,7 +71,7 @@ public String toString() { } @Override - public boolean isEqualTo(Node o) { + public boolean isEqualTo(@Nullable Node o) { if (this == o) { return true; } @@ -111,8 +114,8 @@ public static Builder newFloatValue(BigDecimal value) { } public static final class Builder implements NodeBuilder { - private SourceLocation sourceLocation; - private BigDecimal value; + private @Nullable SourceLocation sourceLocation; + private @Nullable BigDecimal value; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -128,7 +131,7 @@ private Builder(FloatValue existing) { } - public Builder sourceLocation(SourceLocation sourceLocation) { + public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/IntValue.java b/src/main/java/graphql/language/IntValue.java index dc6509c385..ceb197d6bc 100644 --- a/src/main/java/graphql/language/IntValue.java +++ b/src/main/java/graphql/language/IntValue.java @@ -6,6 +6,8 @@ import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.math.BigInteger; import java.util.LinkedHashMap; @@ -21,12 +23,13 @@ import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; @PublicApi +@NullMarked public class IntValue extends AbstractNode implements ScalarValue { private final BigInteger value; @Internal - protected IntValue(BigInteger value, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + protected IntValue(BigInteger value, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { super(sourceLocation, comments, ignoredChars, additionalData); this.value = value; } @@ -61,7 +64,7 @@ public IntValue withNewChildren(NodeChildrenContainer newChildren) { } @Override - public boolean isEqualTo(Node o) { + public boolean isEqualTo(@Nullable Node o) { if (this == o) { return true; } @@ -110,8 +113,8 @@ public IntValue transform(Consumer builderConsumer) { } public static final class Builder implements NodeBuilder { - private SourceLocation sourceLocation; - private BigInteger value; + private @Nullable SourceLocation sourceLocation; + private @Nullable BigInteger value; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -126,7 +129,7 @@ private Builder(IntValue existing) { this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } - public Builder sourceLocation(SourceLocation sourceLocation) { + public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/Node.java b/src/main/java/graphql/language/Node.java index b1c662dfcd..962934d76b 100644 --- a/src/main/java/graphql/language/Node.java +++ b/src/main/java/graphql/language/Node.java @@ -4,6 +4,7 @@ import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.Nullable; import java.io.Serializable; import java.util.List; @@ -47,6 +48,7 @@ public interface Node extends Serializable { /** * @return the source location where this node occurs */ + @Nullable SourceLocation getSourceLocation(); /** @@ -82,7 +84,7 @@ public interface Node extends Serializable { * * @return isEqualTo */ - boolean isEqualTo(Node node); + boolean isEqualTo(@Nullable Node node); /** * @return a deep copy of this node diff --git a/src/main/java/graphql/language/NullValue.java b/src/main/java/graphql/language/NullValue.java index b54cc593d5..d2f49a8990 100644 --- a/src/main/java/graphql/language/NullValue.java +++ b/src/main/java/graphql/language/NullValue.java @@ -7,6 +7,8 @@ import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; import java.util.List; @@ -19,10 +21,11 @@ import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; @PublicApi +@NullMarked public class NullValue extends AbstractNode implements Value { @Internal - protected NullValue(SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + protected NullValue(@Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { super(sourceLocation, comments, ignoredChars, additionalData); } @@ -47,7 +50,7 @@ public NullValue withNewChildren(NodeChildrenContainer newChildren) { } @Override - public boolean isEqualTo(Node o) { + public boolean isEqualTo(@Nullable Node o) { if (this == o) { return true; } @@ -87,7 +90,7 @@ public NullValue transform(Consumer builderConsumer) { } public static final class Builder implements NodeBuilder { - private SourceLocation sourceLocation; + private @Nullable SourceLocation sourceLocation; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -102,7 +105,7 @@ private Builder(NullValue existing) { private Builder() { } - public Builder sourceLocation(SourceLocation sourceLocation) { + public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/ObjectValue.java b/src/main/java/graphql/language/ObjectValue.java index 6c7ee98041..5eb3f4eea0 100644 --- a/src/main/java/graphql/language/ObjectValue.java +++ b/src/main/java/graphql/language/ObjectValue.java @@ -7,6 +7,8 @@ import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; import java.util.List; @@ -18,6 +20,7 @@ import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; @PublicApi +@NullMarked public class ObjectValue extends AbstractNode implements Value { private final ImmutableList objectFields; @@ -25,7 +28,7 @@ public class ObjectValue extends AbstractNode implements Value objectFields, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + protected ObjectValue(List objectFields, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { super(sourceLocation, comments, ignoredChars, additionalData); this.objectFields = ImmutableList.copyOf(objectFields); } @@ -63,7 +66,7 @@ public ObjectValue withNewChildren(NodeChildrenContainer newChildren) { } @Override - public boolean isEqualTo(Node o) { + public boolean isEqualTo(@Nullable Node o) { if (this == o) { return true; } @@ -105,7 +108,7 @@ public ObjectValue transform(Consumer builderConsumer) { } public static final class Builder implements NodeBuilder { - private SourceLocation sourceLocation; + private @Nullable SourceLocation sourceLocation; private ImmutableList objectFields = emptyList(); private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; @@ -121,7 +124,7 @@ private Builder(ObjectValue existing) { this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } - public Builder sourceLocation(SourceLocation sourceLocation) { + public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/ScalarValue.java b/src/main/java/graphql/language/ScalarValue.java index 7ddacb168f..25166972aa 100644 --- a/src/main/java/graphql/language/ScalarValue.java +++ b/src/main/java/graphql/language/ScalarValue.java @@ -1,7 +1,9 @@ package graphql.language; import graphql.PublicApi; +import org.jspecify.annotations.NullMarked; @PublicApi +@NullMarked public interface ScalarValue extends Value { } diff --git a/src/main/java/graphql/language/StringValue.java b/src/main/java/graphql/language/StringValue.java index 74d51ababb..46740ecff7 100644 --- a/src/main/java/graphql/language/StringValue.java +++ b/src/main/java/graphql/language/StringValue.java @@ -6,6 +6,8 @@ import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; import java.util.List; @@ -20,12 +22,13 @@ import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; @PublicApi +@NullMarked public class StringValue extends AbstractNode implements ScalarValue { - private final String value; + private final @Nullable String value; @Internal - protected StringValue(String value, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + protected StringValue(@Nullable String value, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { super(sourceLocation, comments, ignoredChars, additionalData); this.value = value; } @@ -39,7 +42,7 @@ public StringValue(String value) { this(value, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } - public String getValue() { + public @Nullable String getValue() { return value; } @@ -67,7 +70,7 @@ public String toString() { } @Override - public boolean isEqualTo(Node o) { + public boolean isEqualTo(@Nullable Node o) { if (this == o) { return true; } @@ -110,8 +113,8 @@ public StringValue transform(Consumer builderConsumer) { } public static final class Builder implements NodeBuilder { - private SourceLocation sourceLocation; - private String value; + private @Nullable SourceLocation sourceLocation; + private @Nullable String value; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -128,12 +131,12 @@ private Builder(StringValue existing) { } - public Builder sourceLocation(SourceLocation sourceLocation) { + public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } - public Builder value(String value) { + public Builder value(@Nullable String value) { this.value = value; return this; } diff --git a/src/main/java/graphql/language/Value.java b/src/main/java/graphql/language/Value.java index 08cfecbe29..ccb477a913 100644 --- a/src/main/java/graphql/language/Value.java +++ b/src/main/java/graphql/language/Value.java @@ -2,8 +2,10 @@ import graphql.PublicApi; +import org.jspecify.annotations.NullMarked; @PublicApi +@NullMarked public interface Value extends Node { } diff --git a/src/main/java/graphql/language/VariableReference.java b/src/main/java/graphql/language/VariableReference.java index 335e7bb6ea..51958f2df4 100644 --- a/src/main/java/graphql/language/VariableReference.java +++ b/src/main/java/graphql/language/VariableReference.java @@ -6,6 +6,8 @@ import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; import java.util.List; @@ -20,12 +22,13 @@ import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; @PublicApi +@NullMarked public class VariableReference extends AbstractNode implements Value, NamedNode { private final String name; @Internal - protected VariableReference(String name, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + protected VariableReference(String name, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; } @@ -61,7 +64,7 @@ public VariableReference withNewChildren(NodeChildrenContainer newChildren) { } @Override - public boolean isEqualTo(Node o) { + public boolean isEqualTo(@Nullable Node o) { if (this == o) { return true; } @@ -106,9 +109,9 @@ public VariableReference transform(Consumer builderConsumer) { } public static final class Builder implements NodeBuilder { - private SourceLocation sourceLocation; + private @Nullable SourceLocation sourceLocation; private ImmutableList comments = emptyList(); - private String name; + private @Nullable String name; private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -123,7 +126,7 @@ private Builder(VariableReference existing) { this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } - public Builder sourceLocation(SourceLocation sourceLocation) { + public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } From 237ee1f4b34ffac0cf63e82e8a903521bf644654 Mon Sep 17 00:00:00 2001 From: dondonz <13839920+dondonz@users.noreply.github.com> Date: Sun, 3 Aug 2025 10:28:14 +1000 Subject: [PATCH 2/7] Set builders to null unmarked --- src/main/java/graphql/language/ArrayValue.java | 6 ++++-- src/main/java/graphql/language/BooleanValue.java | 6 ++++-- src/main/java/graphql/language/EnumValue.java | 8 +++++--- src/main/java/graphql/language/FloatValue.java | 8 +++++--- src/main/java/graphql/language/IntValue.java | 8 +++++--- src/main/java/graphql/language/NodeBuilder.java | 2 ++ src/main/java/graphql/language/NullValue.java | 6 ++++-- src/main/java/graphql/language/VariableReference.java | 8 +++++--- 8 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/main/java/graphql/language/ArrayValue.java b/src/main/java/graphql/language/ArrayValue.java index c4b4ce6858..d01e7cd1a0 100644 --- a/src/main/java/graphql/language/ArrayValue.java +++ b/src/main/java/graphql/language/ArrayValue.java @@ -8,6 +8,7 @@ import graphql.util.TraversalControl; import graphql.util.TraverserContext; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; @@ -104,8 +105,9 @@ public ArrayValue transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { - private @Nullable SourceLocation sourceLocation; + private SourceLocation sourceLocation; private ImmutableList values = emptyList(); private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; @@ -122,7 +124,7 @@ private Builder(ArrayValue existing) { this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } - public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { + public Builder sourceLocation(SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/BooleanValue.java b/src/main/java/graphql/language/BooleanValue.java index 38dc621f4e..c1fd7e3450 100644 --- a/src/main/java/graphql/language/BooleanValue.java +++ b/src/main/java/graphql/language/BooleanValue.java @@ -7,6 +7,7 @@ import graphql.util.TraversalControl; import graphql.util.TraverserContext; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; @@ -112,8 +113,9 @@ public BooleanValue transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { - private @Nullable SourceLocation sourceLocation; + private SourceLocation sourceLocation; private boolean value; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; @@ -131,7 +133,7 @@ private Builder(BooleanValue existing) { } - public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { + public Builder sourceLocation(SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/EnumValue.java b/src/main/java/graphql/language/EnumValue.java index fdd03b9604..4164b6c68b 100644 --- a/src/main/java/graphql/language/EnumValue.java +++ b/src/main/java/graphql/language/EnumValue.java @@ -7,6 +7,7 @@ import graphql.util.TraversalControl; import graphql.util.TraverserContext; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; @@ -114,9 +115,10 @@ public EnumValue transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { - private @Nullable SourceLocation sourceLocation; - private @Nullable String name; + private SourceLocation sourceLocation; + private String name; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -132,7 +134,7 @@ private Builder(EnumValue existing) { } - public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { + public Builder sourceLocation(SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/FloatValue.java b/src/main/java/graphql/language/FloatValue.java index f3712dbc59..c27cbd444b 100644 --- a/src/main/java/graphql/language/FloatValue.java +++ b/src/main/java/graphql/language/FloatValue.java @@ -7,6 +7,7 @@ import graphql.util.TraversalControl; import graphql.util.TraverserContext; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import java.math.BigDecimal; @@ -113,9 +114,10 @@ public static Builder newFloatValue(BigDecimal value) { return new Builder().value(value); } + @NullUnmarked public static final class Builder implements NodeBuilder { - private @Nullable SourceLocation sourceLocation; - private @Nullable BigDecimal value; + private SourceLocation sourceLocation; + private BigDecimal value; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -131,7 +133,7 @@ private Builder(FloatValue existing) { } - public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { + public Builder sourceLocation(SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/IntValue.java b/src/main/java/graphql/language/IntValue.java index ceb197d6bc..5a197646d9 100644 --- a/src/main/java/graphql/language/IntValue.java +++ b/src/main/java/graphql/language/IntValue.java @@ -7,6 +7,7 @@ import graphql.util.TraversalControl; import graphql.util.TraverserContext; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import java.math.BigInteger; @@ -112,9 +113,10 @@ public IntValue transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { - private @Nullable SourceLocation sourceLocation; - private @Nullable BigInteger value; + private SourceLocation sourceLocation; + private BigInteger value; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -129,7 +131,7 @@ private Builder(IntValue existing) { this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } - public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { + public Builder sourceLocation(SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/NodeBuilder.java b/src/main/java/graphql/language/NodeBuilder.java index df88e16632..88aaf63c82 100644 --- a/src/main/java/graphql/language/NodeBuilder.java +++ b/src/main/java/graphql/language/NodeBuilder.java @@ -1,11 +1,13 @@ package graphql.language; import graphql.PublicApi; +import org.jspecify.annotations.NullUnmarked; import java.util.List; import java.util.Map; @PublicApi +@NullUnmarked public interface NodeBuilder { NodeBuilder sourceLocation(SourceLocation sourceLocation); diff --git a/src/main/java/graphql/language/NullValue.java b/src/main/java/graphql/language/NullValue.java index d2f49a8990..9e053acae2 100644 --- a/src/main/java/graphql/language/NullValue.java +++ b/src/main/java/graphql/language/NullValue.java @@ -8,6 +8,7 @@ import graphql.util.TraversalControl; import graphql.util.TraverserContext; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; @@ -89,8 +90,9 @@ public NullValue transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { - private @Nullable SourceLocation sourceLocation; + private SourceLocation sourceLocation; private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -105,7 +107,7 @@ private Builder(NullValue existing) { private Builder() { } - public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { + public Builder sourceLocation(SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } diff --git a/src/main/java/graphql/language/VariableReference.java b/src/main/java/graphql/language/VariableReference.java index 51958f2df4..69fd14acf6 100644 --- a/src/main/java/graphql/language/VariableReference.java +++ b/src/main/java/graphql/language/VariableReference.java @@ -7,6 +7,7 @@ import graphql.util.TraversalControl; import graphql.util.TraverserContext; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; @@ -108,10 +109,11 @@ public VariableReference transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { - private @Nullable SourceLocation sourceLocation; + private SourceLocation sourceLocation; private ImmutableList comments = emptyList(); - private @Nullable String name; + private String name; private IgnoredChars ignoredChars = IgnoredChars.EMPTY; private Map additionalData = new LinkedHashMap<>(); @@ -126,7 +128,7 @@ private Builder(VariableReference existing) { this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } - public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { + public Builder sourceLocation(SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } From d559d7bb30fdb6e32f2a1eef65277a1399c3d05d Mon Sep 17 00:00:00 2001 From: dondonz <13839920+dondonz@users.noreply.github.com> Date: Sun, 3 Aug 2025 10:29:00 +1000 Subject: [PATCH 3/7] Require array and object value to not be null, use empty list instead --- src/main/java/graphql/language/AbstractNode.java | 4 ++-- src/main/java/graphql/language/ArrayValue.java | 3 ++- src/main/java/graphql/language/ObjectValue.java | 9 ++++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/graphql/language/AbstractNode.java b/src/main/java/graphql/language/AbstractNode.java index a1bcc83da8..af859ee834 100644 --- a/src/main/java/graphql/language/AbstractNode.java +++ b/src/main/java/graphql/language/AbstractNode.java @@ -59,7 +59,7 @@ public Map getAdditionalData() { } @SuppressWarnings("unchecked") - protected V deepCopy(V nullableObj) { + protected @Nullable V deepCopy(@Nullable V nullableObj) { if (nullableObj == null) { return null; } @@ -67,7 +67,7 @@ public Map getAdditionalData() { } @SuppressWarnings("unchecked") - protected @Nullable List deepCopy(@Nullable List list) { + protected @Nullable List deepCopy(@Nullable List list) { if (list == null) { return null; } diff --git a/src/main/java/graphql/language/ArrayValue.java b/src/main/java/graphql/language/ArrayValue.java index d01e7cd1a0..a3a2de2cbe 100644 --- a/src/main/java/graphql/language/ArrayValue.java +++ b/src/main/java/graphql/language/ArrayValue.java @@ -91,7 +91,8 @@ public String toString() { @Override public ArrayValue deepCopy() { - return new ArrayValue(deepCopy(values), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); + List copiedValues = deepCopy(values); + return new ArrayValue(copiedValues != null ? copiedValues : emptyList(), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override diff --git a/src/main/java/graphql/language/ObjectValue.java b/src/main/java/graphql/language/ObjectValue.java index 5eb3f4eea0..8792bb5f92 100644 --- a/src/main/java/graphql/language/ObjectValue.java +++ b/src/main/java/graphql/language/ObjectValue.java @@ -8,6 +8,7 @@ import graphql.util.TraversalControl; import graphql.util.TraverserContext; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import java.util.LinkedHashMap; @@ -80,7 +81,8 @@ public boolean isEqualTo(@Nullable Node o) { @Override public ObjectValue deepCopy() { - return new ObjectValue(deepCopy(objectFields), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); + List copiedFields = deepCopy(objectFields); + return new ObjectValue(copiedFields != null ? copiedFields : emptyList(), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @@ -107,8 +109,9 @@ public ObjectValue transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { - private @Nullable SourceLocation sourceLocation; + private SourceLocation sourceLocation; private ImmutableList objectFields = emptyList(); private ImmutableList comments = emptyList(); private IgnoredChars ignoredChars = IgnoredChars.EMPTY; @@ -124,7 +127,7 @@ private Builder(ObjectValue existing) { this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } - public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { + public Builder sourceLocation(SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } From 5dd0424dd142130578fb6401b5c870872f09b15e Mon Sep 17 00:00:00 2001 From: dondonz <13839920+dondonz@users.noreply.github.com> Date: Sun, 10 Aug 2025 09:16:04 +1000 Subject: [PATCH 4/7] Fix up nullability annotation --- src/main/java/graphql/language/AbstractNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/graphql/language/AbstractNode.java b/src/main/java/graphql/language/AbstractNode.java index af859ee834..c300230dbb 100644 --- a/src/main/java/graphql/language/AbstractNode.java +++ b/src/main/java/graphql/language/AbstractNode.java @@ -59,7 +59,7 @@ public Map getAdditionalData() { } @SuppressWarnings("unchecked") - protected @Nullable V deepCopy(@Nullable V nullableObj) { + protected @Nullable V deepCopy(@Nullable V nullableObj) { if (nullableObj == null) { return null; } @@ -67,7 +67,7 @@ public Map getAdditionalData() { } @SuppressWarnings("unchecked") - protected @Nullable List deepCopy(@Nullable List list) { + protected @Nullable List deepCopy(@Nullable List list) { if (list == null) { return null; } From 0393ee9cbf6786d524693d0f109924119e73e5e1 Mon Sep 17 00:00:00 2001 From: dondonz <13839920+dondonz@users.noreply.github.com> Date: Sun, 10 Aug 2025 10:09:48 +1000 Subject: [PATCH 5/7] Add assertion --- src/main/java/graphql/language/ArrayValue.java | 5 +++-- src/main/java/graphql/language/ObjectValue.java | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/graphql/language/ArrayValue.java b/src/main/java/graphql/language/ArrayValue.java index a3a2de2cbe..053fffe6d1 100644 --- a/src/main/java/graphql/language/ArrayValue.java +++ b/src/main/java/graphql/language/ArrayValue.java @@ -14,6 +14,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; import static graphql.Assert.assertNotNull; @@ -91,8 +92,8 @@ public String toString() { @Override public ArrayValue deepCopy() { - List copiedValues = deepCopy(values); - return new ArrayValue(copiedValues != null ? copiedValues : emptyList(), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); + List copiedValues = Objects.requireNonNull(deepCopy(values)); + return new ArrayValue(copiedValues, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override diff --git a/src/main/java/graphql/language/ObjectValue.java b/src/main/java/graphql/language/ObjectValue.java index 8792bb5f92..0bffc6c933 100644 --- a/src/main/java/graphql/language/ObjectValue.java +++ b/src/main/java/graphql/language/ObjectValue.java @@ -14,6 +14,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; import static graphql.Assert.assertNotNull; @@ -81,8 +82,8 @@ public boolean isEqualTo(@Nullable Node o) { @Override public ObjectValue deepCopy() { - List copiedFields = deepCopy(objectFields); - return new ObjectValue(copiedFields != null ? copiedFields : emptyList(), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); + List copiedFields = Objects.requireNonNull(deepCopy(objectFields)); + return new ObjectValue(copiedFields, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } From b124c002f713d72d00cbe92ebca7b6ec055d5f8c Mon Sep 17 00:00:00 2001 From: dondonz <13839920+dondonz@users.noreply.github.com> Date: Sun, 10 Aug 2025 10:11:53 +1000 Subject: [PATCH 6/7] Change to assert --- src/main/java/graphql/language/ArrayValue.java | 3 +-- src/main/java/graphql/language/ObjectValue.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/graphql/language/ArrayValue.java b/src/main/java/graphql/language/ArrayValue.java index 053fffe6d1..2d5ae6c100 100644 --- a/src/main/java/graphql/language/ArrayValue.java +++ b/src/main/java/graphql/language/ArrayValue.java @@ -14,7 +14,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.function.Consumer; import static graphql.Assert.assertNotNull; @@ -92,7 +91,7 @@ public String toString() { @Override public ArrayValue deepCopy() { - List copiedValues = Objects.requireNonNull(deepCopy(values)); + List copiedValues = assertNotNull(deepCopy(values)); return new ArrayValue(copiedValues, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } diff --git a/src/main/java/graphql/language/ObjectValue.java b/src/main/java/graphql/language/ObjectValue.java index 0bffc6c933..7a40d0a4c9 100644 --- a/src/main/java/graphql/language/ObjectValue.java +++ b/src/main/java/graphql/language/ObjectValue.java @@ -14,7 +14,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.function.Consumer; import static graphql.Assert.assertNotNull; @@ -82,7 +81,7 @@ public boolean isEqualTo(@Nullable Node o) { @Override public ObjectValue deepCopy() { - List copiedFields = Objects.requireNonNull(deepCopy(objectFields)); + List copiedFields = assertNotNull(deepCopy(objectFields)); return new ObjectValue(copiedFields, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } From d7f087ec4c5e4b541f0960e2ec29996df385a796 Mon Sep 17 00:00:00 2001 From: dondonz <13839920+dondonz@users.noreply.github.com> Date: Sun, 10 Aug 2025 10:38:02 +1000 Subject: [PATCH 7/7] Update exemptions --- .../archunit/JSpecifyAnnotationsCheck.groovy | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/test/groovy/graphql/archunit/JSpecifyAnnotationsCheck.groovy b/src/test/groovy/graphql/archunit/JSpecifyAnnotationsCheck.groovy index ee8e4aec58..c32efb2826 100644 --- a/src/test/groovy/graphql/archunit/JSpecifyAnnotationsCheck.groovy +++ b/src/test/groovy/graphql/archunit/JSpecifyAnnotationsCheck.groovy @@ -130,15 +130,12 @@ class JSpecifyAnnotationsCheck extends Specification { "graphql.introspection.IntrospectionWithDirectivesSupport", "graphql.introspection.IntrospectionWithDirectivesSupport\$DirectivePredicateEnvironment", "graphql.language.AbstractDescribedNode", - "graphql.language.AbstractNode", "graphql.language.Argument", - "graphql.language.ArrayValue", "graphql.language.AstNodeAdapter", "graphql.language.AstPrinter", "graphql.language.AstSignature", "graphql.language.AstSorter", "graphql.language.AstTransformer", - "graphql.language.BooleanValue", "graphql.language.Comment", "graphql.language.Definition", "graphql.language.DescribedNode", @@ -150,11 +147,9 @@ class JSpecifyAnnotationsCheck extends Specification { "graphql.language.Document", "graphql.language.EnumTypeDefinition", "graphql.language.EnumTypeExtensionDefinition", - "graphql.language.EnumValue", "graphql.language.EnumValueDefinition", "graphql.language.Field", "graphql.language.FieldDefinition", - "graphql.language.FloatValue", "graphql.language.FragmentDefinition", "graphql.language.FragmentSpread", "graphql.language.IgnoredChar", @@ -164,13 +159,11 @@ class JSpecifyAnnotationsCheck extends Specification { "graphql.language.InputObjectTypeDefinition", "graphql.language.InputObjectTypeExtensionDefinition", "graphql.language.InputValueDefinition", - "graphql.language.IntValue", "graphql.language.InterfaceTypeDefinition", "graphql.language.InterfaceTypeExtensionDefinition", "graphql.language.ListType", "graphql.language.NamedNode", "graphql.language.Node", - "graphql.language.NodeBuilder", "graphql.language.NodeChildrenContainer", "graphql.language.NodeDirectivesBuilder", "graphql.language.NodeParentTree", @@ -178,11 +171,9 @@ class JSpecifyAnnotationsCheck extends Specification { "graphql.language.NodeVisitor", "graphql.language.NodeVisitorStub", "graphql.language.NonNullType", - "graphql.language.NullValue", "graphql.language.ObjectField", "graphql.language.ObjectTypeDefinition", "graphql.language.ObjectTypeExtensionDefinition", - "graphql.language.ObjectValue", "graphql.language.OperationDefinition", "graphql.language.OperationTypeDefinition", "graphql.language.PrettyAstPrinter", @@ -191,23 +182,19 @@ class JSpecifyAnnotationsCheck extends Specification { "graphql.language.SDLNamedDefinition", "graphql.language.ScalarTypeDefinition", "graphql.language.ScalarTypeExtensionDefinition", - "graphql.language.ScalarValue", "graphql.language.SchemaDefinition", "graphql.language.SchemaExtensionDefinition", "graphql.language.Selection", "graphql.language.SelectionSet", "graphql.language.SelectionSetContainer", "graphql.language.SourceLocation", - "graphql.language.StringValue", "graphql.language.Type", "graphql.language.TypeDefinition", "graphql.language.TypeKind", "graphql.language.TypeName", "graphql.language.UnionTypeDefinition", "graphql.language.UnionTypeExtensionDefinition", - "graphql.language.Value", "graphql.language.VariableDefinition", - "graphql.language.VariableReference", "graphql.normalized.ExecutableNormalizedField", "graphql.normalized.ExecutableNormalizedOperation", "graphql.normalized.ExecutableNormalizedOperationFactory",