Skip to content

Conversation

@dondonz
Copy link
Member

@dondonz dondonz commented Dec 4, 2025

We have many classes left to go for JSpecify, so rather than one class at a time I will do the remainder in large bundles. This adds annotations on ~50 classes.

The general recipe here is

  • Use IntelliJ's infer nullity tool, which is a start and covers the basics
  • AI prompt to read JavaDoc, inspect nearby methods, with self-verification using NullAway
  • And finally a manual check from me, as some items are hard to infer nullity without understanding the GraphQL specification or the codebase

What will be in a future PR: better Kotlin tooling as reported recently in #4179

"graphql.validation.ValidationError",
"graphql.validation.ValidationErrorClassification",
"graphql.validation.ValidationErrorType",
// These classes will not be public API later, exempt here while marked as experimental
Copy link
Member Author

Choose a reason for hiding this comment

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

There is an edge case where some classes have been annotated with "Experimental API" for the purposes of the defer work. They won't become public API later so I made a note in the JSpecify exemption rule

private final List<SourceLocation> locations;
private final Map<String, Object> extensions;
private final List<Object> path;
private final @Nullable List<SourceLocation> locations;
Copy link
Member Author

@dondonz dondonz Dec 7, 2025

Choose a reason for hiding this comment

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

The builder creates a non-nullable list, but that's only if the builder is called

@dondonz dondonz marked this pull request as ready for review December 7, 2025 04:13
* @return a value or null
*/
public <T> T get(Object key) {
public <T> @Nullable T get(Object key) {
Copy link
Member Author

Choose a reason for hiding this comment

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

TODO: another case of the nullable generic issue

Copy link
Member Author

Choose a reason for hiding this comment

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

Update - all values stored in the GraphQLContext are non-null. It's only going to return null if the key is not found. Let's keep it like this.

*/
@SuppressWarnings("unchecked")
public <T> T getObject() {
public @Nullable <T> T getObject() {
Copy link
Member Author

Choose a reason for hiding this comment

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

TODO: another generic nullable check

Copy link
Member Author

Choose a reason for hiding this comment

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

Edit: object should also be nullable

Copy link
Member Author

Choose a reason for hiding this comment

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

I updated the prompt with more information on generics

@dondonz
Copy link
Member Author

dondonz commented Jan 26, 2026

I had a fix a bunch of tests when I changed Validation Error messages to be non-nullable

This is as per the spec - messages in GraphQL errors must be present

@dondonz dondonz merged commit 2f0dc5b into master Feb 11, 2026
7 checks passed
@dondonz
Copy link
Member Author

dondonz commented Feb 11, 2026

Special note for release notes: ValidationError technically has a breaking change, now a description must be not-nullable, which is consistent with the specification

Previously there was a mismatch that ValidationError didn't enforce description. However that doesn't make much sense, if a user receives a validation error they should also receive a description to help explain and diagnose the error

@dondonz dondonz added the breaking change requires a new major version to be relased label Feb 11, 2026
@@ -0,0 +1,59 @@
The task is to annotate public API classes (marked with `@PublicAPI`) with JSpecify nullability annotations.
Copy link
Member Author

Choose a reason for hiding this comment

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

This prompt is checked in so subagents can all share this context

This prompt will be deleted after this series of JSpecify annotations is completed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change requires a new major version to be relased

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant