-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Specify nullness for nodes in the graphql.language
package
#3899
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR applies nullability annotations across the graphql.language package to clarify which fields and parameters can be null.
- Added @NullMarked and @nullable annotations to key classes and constructors.
- Updated Builder classes for several Value types to accept null parameters.
- Adjusted method signatures (e.g. isEqualTo) and field declarations to reflect nullability.
Reviewed Changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
File | Description |
---|---|
VariableReference.java | Annotated the class and its Builder with nullability hints. |
Value.java | Marked the interface with @NullMarked. |
StringValue.java | Adjusted the field and getter for value to be @nullable. |
ScalarValue.java | Applied @NullMarked to the interface. |
ObjectValue.java | Annotated constructors and Builder methods with @nullable. |
NullValue.java | Updated constructor and Builder to support null SourceLocation. |
Node.java | Updated getSourceLocation and isEqualTo for nullability. |
IntValue.java, FloatValue.java, EnumValue.java, BooleanValue.java, ArrayValue.java, AbstractNode.java | Applied similar nullability annotations to constructors, methods, and Builder classes. |
private ImmutableList<Comment> comments = emptyList(); | ||
private String name; | ||
private @Nullable String name; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The VariableReference.Builder now allows a null name. Consider adding validation in the build() method to ensure that a non-null name is provided if that is an invariant in your domain.
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name
in the above constructor and builder method are not nullable, did you meant to make this field nullable?
I think in practice, a VariableReference should always have a non-nullable name
private SourceLocation sourceLocation; | ||
private String name; | ||
private @Nullable SourceLocation sourceLocation; | ||
private @Nullable String name; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The EnumValue.Builder permits a null name. It may be beneficial to enforce a non-null name during object construction if that is required by the API contract.
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello, thanks for your patience while away for Easter.
In this builder, name is set to nullable, but the constructor above has name as non-nullable, and the builder method below has it as non-nullable. Did you mean for the Builder's name to be instead non-nullable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, nullable fields in the builder are expected.
By default, when a builder instance is created, all values are set to their defaults (null for reference fields) - thus, it's necessary to mark these fields @Nullable
.
This initial Builder
state represents an incomplete configuration, and the EnumValue
should not be constructible in this state - calling the build()
method should result in an IllegalStateException
.
I planned to add something like this later:
public EnumValue build() {
if (name == null) {
throw new IllegalStateException("name must be set");
}
return new EnumValue(name, sourceLocation, comments, ignoredChars, additionalData);
}
private SourceLocation sourceLocation; | ||
private BigInteger value; | ||
private @Nullable SourceLocation sourceLocation; | ||
private @Nullable BigInteger value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The IntValue.Builder now accepts a null value. Consider adding a check in the build() method to prevent creating an IntValue instance with a null value if that contradicts expected behavior.
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as for FloatValue, I will double check if a null value
is in practice possible or not
private SourceLocation sourceLocation; | ||
private BigDecimal value; | ||
private @Nullable SourceLocation sourceLocation; | ||
private @Nullable BigDecimal value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FloatValue.Builder now permits a null value. If a non-null value is expected, it would be prudent to validate this in the build() method to prevent possible misuse, as noted in the PR description.
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This builder should be consistent with the constructor for value
@andimarek @bbakerman: is it possible in practice for FloatValue
to ever be constructed with a null? Or would such an object always be constructed as a NullValue
?
Giving Copilot a try for fun, I'm curious what it says |
private SourceLocation sourceLocation; | ||
private String value; | ||
private @Nullable SourceLocation sourceLocation; | ||
private @Nullable String value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to above Value classes, I will double check if value can be nullable or if in practice it is represented by a NullValue
Coming back in here to say thanks for waiting and thanks for the PR. We have a new PR up to add ErrorProne & NullAway checks which I'd like to merge in before new JSpecify PRs |
Related: #3878
I applied
@NullMarked
and@Nullable
annotations to these classes:graphql.language.Node
- partially annotated with@Nullable
graphql.language.AbstractNode
graphql.language.ArrayValue
graphql.language.BooleanValue
graphql.language.EnumValue
graphql.language.FloatValue
graphql.language.IntValue
graphql.language.NullValue
graphql.language.ObjectValue
graphql.language.ScalarValue
graphql.language.StringValue
- I was not sure about the nullability ofvalue
, for now I marked it@Nullable
.graphql.language.Value
graphql.language.VariableReference
Notes
SourceLocation sourceLocation
- can contain a null value in all placesPotential problems (will be pointed by #3852 )
EnumValue.Builder#build()
can build anEnumValue
object with a nullname
FloatValue.Builder#build()
can build anFloatValue
object with a nullvalue
IntValue.Builder#build()
can build anIntValue
object with a nullvalue
VariableReference.Builder#build()
can build anVariableReference
object with a nullname