Skip to content

JSpecify big wave 3#4274

Draft
dondonz wants to merge 73 commits intomasterfrom
claude/agent-team-jspecify-Frd74
Draft

JSpecify big wave 3#4274
dondonz wants to merge 73 commits intomasterfrom
claude/agent-team-jspecify-Frd74

Conversation

@dondonz
Copy link
Member

@dondonz dondonz commented Mar 1, 2026

Another wave of JSpecify changes, this time featuring Claude's agent teams.

Keeping in draft while I review.


66 classes annotated

graphql.analysis (16 classes)

QueryComplexityCalculator, QueryComplexityInfo, QueryDepthInfo, QueryReducer, QueryTransformer, QueryTraversalOptions, QueryVisitor, QueryVisitorFieldArgumentEnvironment, QueryVisitorFieldArgumentInputValue, QueryVisitorFieldArgumentValueEnvironment, QueryVisitorFieldEnvironment, QueryVisitorFragmentDefinitionEnvironment, QueryVisitorFragmentSpreadEnvironment, QueryVisitorInlineFragmentEnvironment, QueryVisitorStub, ValueTraverser

graphql.execution core (26 classes)

AbortExecutionException, AsyncExecutionStrategy, AsyncSerialExecutionStrategy, CoercedVariables, DataFetcherExceptionHandlerParameters, DataFetcherExceptionHandlerResult, DefaultValueUnboxer, ExecutionContext, ExecutionId, ExecutionStepInfo, ExecutionStrategyParameters, FetchedValue, FieldValueInfo, InputMapDefinesTooManyFieldsException, MergedSelectionSet, MissingRootTypeException, NonNullableValueCoercedAsNullException, NormalizedVariables, OneOfNullValueException, OneOfTooManyKeysException, ResultNodesInfo, ResultPath, SimpleDataFetcherExceptionHandler, SubscriptionExecutionStrategy, UnknownOperationException, UnresolvedTypeException

graphql.execution sub-packages (24 classes)

ConditionalNodeDecision, QueryAppliedDirective, QueryAppliedDirectiveArgument, QueryDirectives, FieldValidationInstrumentation, SimpleFieldValidation, InstrumentationCreateStateParameters, InstrumentationExecuteOperationParameters, InstrumentationExecutionParameters, InstrumentationExecutionStrategyParameters, InstrumentationFieldCompleteParameters, InstrumentationFieldFetchParameters, InstrumentationFieldParameters, InstrumentationValidationParameters, TracingInstrumentation, TracingSupport, PreparsedDocumentEntry, ApolloPersistedQuerySupport, InMemoryPersistedQueryCache, PersistedQueryCacheMiss, PersistedQueryIdInvalid, PersistedQueryNotFound, DelegatingSubscription, SubscriptionPublisher

Review passes

./gradlew compileJava passes. The reviewer agent also fixed cascading NullAway errors in calling code (e.g. ResultPath, ExecutionStepInfo, ExecutionContext, TracingSupport) using assertNotNull() where structural invariants guarantee non-null.

claude and others added 30 commits February 28, 2026 23:21
dondonz and others added 18 commits March 1, 2026 10:40
- QueryAppliedDirectiveArgument: remove @nonnull from Builder methods (import was dropped)
- ResultPath: fix @nullable parent/segment dereferences with assertNotNull
- ExecutionStepInfo: fix @nullable field dereference in getResultKey()
- ExecutionContext: add assertNotNull for AtomicReference.get() calls on errors
- SubscriptionExecutionStrategy: fix @nullable getField()/getDeferredCallContext() dereferences
- AsyncSerialExecutionStrategy: fix @nullable getSubField()/getFieldValueObject() issues
- DataFetcherExceptionHandlerParameters: mark getSourceLocation() @nullable
- ExceptionWhileDataFetching: accept @nullable SourceLocation in constructor
- TracingSupport/UnresolvedTypeError: fix @nullable getParent()/getFieldDefinition() dereferences
- InstrumentationFieldParameters/Complete: fix @nullable getFieldDefinition() in getField()
- ExecutionStepInfoFactory: fix @nullable getField() with assertNotNull
- GraphQL: fix @nullable getDocument() with assertNotNull
- ValueTraverser: fix @nullable newValue passed to ImmutableList.Builder.add()
- MaxQueryDepthInstrumentation: mark getPathLength() param @nullable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* This Exception indicates that the current execution should be aborted.
*/
@PublicApi
@NullMarked
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 abruptly ran out of credits here - more is coming

Copy link
Member Author

Choose a reason for hiding this comment

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

Given it's already 66 classes - the next wave will happen in a separate PR

Copy link
Member

Choose a reason for hiding this comment

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

Image

@github-actions
Copy link
Contributor

github-actions bot commented Mar 1, 2026

Test Results

  335 files  ±0    335 suites  ±0   5m 4s ⏱️ -2s
5 378 tests ±0  5 369 ✅  - 1  9 💤 +1  0 ❌ ±0 
5 467 runs  ±0  5 458 ✅  - 1  9 💤 +1  0 ❌ ±0 

Results for commit 0a77532. ± Comparison against base commit 739403f.

This pull request removes 196 and adds 172 tests. Note that renamed tests count towards both.
	?

	, expected: combo-\"\\\b\f\n\r\t, #4]
                __schema { types { fields { args { type { name fields { name }}}}}}
                __schema { types { fields { type { name fields { name }}}}}
                __schema { types { inputFields { type { inputFields { name }}}}}
                __schema { types { interfaces { fields { type { interfaces { name } } } } } }
                __schema { types { name} }
                __type(name : "t") { name }
                a1: __schema { types { name} }
                a1: __type(name : "t") { name }
…
graphql.AssertTest ‑ assertFalse with different number of error args but false does not throw assertions [toRun: <graphql.AssertTest$__spock_feature_0_21prov0_closure23@2f2bff16 delegate=inaccessible owner=inaccessible thisObject=inaccessible resolveStrategy=inaccessible directive=inaccessible parameterTypes=inaccessible maximumNumberOfParameters=inaccessible bcw=inaccessible thisType=inaccessible>, expectedMessage: error arg1, #0]
graphql.AssertTest ‑ assertFalse with different number of error args but false does not throw assertions [toRun: <graphql.AssertTest$__spock_feature_0_21prov0_closure24@75de29c0 delegate=inaccessible owner=inaccessible thisObject=inaccessible resolveStrategy=inaccessible directive=inaccessible parameterTypes=inaccessible maximumNumberOfParameters=inaccessible bcw=inaccessible thisType=inaccessible>, expectedMessage: error arg1 arg2, #1]
graphql.AssertTest ‑ assertFalse with different number of error args but false does not throw assertions [toRun: <graphql.AssertTest$__spock_feature_0_21prov0_closure25@fc807c1 delegate=inaccessible owner=inaccessible thisObject=inaccessible resolveStrategy=inaccessible directive=inaccessible parameterTypes=inaccessible maximumNumberOfParameters=inaccessible bcw=inaccessible thisType=inaccessible>, expectedMessage: error arg1 arg2 arg3, #2]
graphql.AssertTest ‑ assertFalse with different number of error args throws assertions [toRun: <graphql.AssertTest$__spock_feature_0_20prov0_closure20@733aa9d8 delegate=inaccessible owner=inaccessible thisObject=inaccessible resolveStrategy=inaccessible directive=inaccessible parameterTypes=inaccessible maximumNumberOfParameters=inaccessible bcw=inaccessible thisType=inaccessible>, expectedMessage: error arg1, #0]
graphql.AssertTest ‑ assertFalse with different number of error args throws assertions [toRun: <graphql.AssertTest$__spock_feature_0_20prov0_closure21@6dcc40f5 delegate=inaccessible owner=inaccessible thisObject=inaccessible resolveStrategy=inaccessible directive=inaccessible parameterTypes=inaccessible maximumNumberOfParameters=inaccessible bcw=inaccessible thisType=inaccessible>, expectedMessage: error arg1 arg2, #1]
graphql.AssertTest ‑ assertFalse with different number of error args throws assertions [toRun: <graphql.AssertTest$__spock_feature_0_20prov0_closure22@2b680207 delegate=inaccessible owner=inaccessible thisObject=inaccessible resolveStrategy=inaccessible directive=inaccessible parameterTypes=inaccessible maximumNumberOfParameters=inaccessible bcw=inaccessible thisType=inaccessible>, expectedMessage: error arg1 arg2 arg3, #2]
graphql.AssertTest ‑ assertNotNull with different number of  error args throws assertions [toRun: <graphql.AssertTest$__spock_feature_0_5prov0_closure3@6eb17ec8 delegate=inaccessible owner=inaccessible thisObject=inaccessible resolveStrategy=inaccessible directive=inaccessible parameterTypes=inaccessible maximumNumberOfParameters=inaccessible bcw=inaccessible thisType=inaccessible>, expectedMessage: error arg1, #0]
graphql.AssertTest ‑ assertNotNull with different number of  error args throws assertions [toRun: <graphql.AssertTest$__spock_feature_0_5prov0_closure4@48d293ee delegate=inaccessible owner=inaccessible thisObject=inaccessible resolveStrategy=inaccessible directive=inaccessible parameterTypes=inaccessible maximumNumberOfParameters=inaccessible bcw=inaccessible thisType=inaccessible>, expectedMessage: error arg1 arg2, #1]
graphql.AssertTest ‑ assertNotNull with different number of  error args throws assertions [toRun: <graphql.AssertTest$__spock_feature_0_5prov0_closure5@7a0ef219 delegate=inaccessible owner=inaccessible thisObject=inaccessible resolveStrategy=inaccessible directive=inaccessible parameterTypes=inaccessible maximumNumberOfParameters=inaccessible bcw=inaccessible thisType=inaccessible>, expectedMessage: error arg1 arg2 arg3, #2]
graphql.AssertTest ‑ assertNotNull with different number of error args with non null does not throw assertions [toRun: <graphql.AssertTest$__spock_feature_0_6prov0_closure6@e5cbff2 delegate=inaccessible owner=inaccessible thisObject=inaccessible resolveStrategy=inaccessible directive=inaccessible parameterTypes=inaccessible maximumNumberOfParameters=inaccessible bcw=inaccessible thisType=inaccessible>, expectedMessage: error arg1, #0]
…
This pull request skips 1 test.
graphql.schema.fetching.LambdaFetchingSupportTest ‑ different class loaders induce certain behaviours

♻️ This comment has been updated with latest results.

All 66 classes annotated in Wave 1 (graphql.analysis, graphql.execution core,
and graphql.execution sub-packages) are removed from the exemption list now
that they carry @NullMarked.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
graphql.execution.reactive.DelegatingSubscription
graphql.execution.reactive.SubscriptionPublisher
```

Copy link
Member Author

Choose a reason for hiding this comment

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

Worker 4 got removed because it was covered by previous PRs.

Work from worker 5 onwards will be in another PR. This PR is already quite large

dondonz and others added 2 commits March 1, 2026 16:18
- Explicitly state that @internal classes must not be annotated
- Tighten exemption list cleanup instruction to remove only the annotated class

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* @return this builder
*/
public Builder valueLiteral(@NonNull Value<?> value) {
public Builder valueLiteral(Value<?> value) {
Copy link
Member

Choose a reason for hiding this comment

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

So you tuned OFF null marked but this is no less precise than it was. Perhaps a Object.requireNonNull ??


@Nullable
public List<? extends GraphQLError> getErrors() {
return errors;
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should change this so that errors is always non null but some times empty?

Document has to nullable of course. Quasi breaking change but nicer - eg less nullable things

Copy link
Member

@bbakerman bbakerman left a comment

Choose a reason for hiding this comment

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

Image

@dondonz
Copy link
Member Author

dondonz commented Mar 7, 2026

I'm impressed, I have the correct number of fingers on both hands. Models have come a long way.

But I'm going to deduct marks for Python references creeping in!

@github-actions
Copy link
Contributor

github-actions bot commented Mar 7, 2026

Test Report

Test Results

Java Version Total Passed Failed Errors Skipped
Java 11 5671 (±0) 5614 (±0) 0 (±0) 0 (±0) 57 (±0)
Java 17 5671 (±0) 5613 (±0) 0 (±0) 0 (±0) 58 (±0)
Java 21 5671 (±0) 5613 (±0) 0 (±0) 0 (±0) 58 (±0)
Java 25 5671 (±0) 5613 (±0) 0 (±0) 0 (±0) 58 (±0)
jcstress 32 (±0) 32 (±0) 0 (±0) 0 (±0) 0 (±0)
Total 22716 (±0) 22485 (±0) 0 (±0) 0 (±0) 231 (±0)

Code Coverage (Java 25)

Metric Covered Missed Coverage vs Master
Lines 28698 3126 90.2% ±0.0%
Branches 8331 1511 84.6% ±0.0%
Methods 7681 1224 86.3% ±0.0%

Changed Class Coverage (1 class)

Class Line Branch Method
g.e.i.d.ExhaustedDataLoaderDispatchStrategy -1.2% 🔴 -7.7% 🔴 ±0.0%

Full HTML report: build artifact jacoco-html-report

Updated: 2026-03-07 20:43:03 UTC

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants