Skip to content

Commit ace4992

Browse files
committed
Resolve nullability issues surfaced by NullAway's JSpecify mode
1 parent 3cf2ef5 commit ace4992

File tree

56 files changed

+233
-178
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+233
-178
lines changed

documentation/src/test/java/example/FirstCustomEngine.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId
4848
return new EngineDescriptor(uniqueId, "First Custom Test Engine");
4949
}
5050

51+
//end::user_guide[]
52+
@SuppressWarnings("NullAway")
53+
//tag::user_guide[]
5154
@Override
5255
public void execute(ExecutionRequest request) {
5356
request.getEngineExecutionListener()

documentation/src/test/java/example/ParameterizedLifecycleDemo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static void beforeInvocation(TextFile textFile, @TempDir Path tempDir) throws Ex
5555
}
5656

5757
//end::user_guide[]
58-
@SuppressWarnings({ "DataFlowIssue", "NullAway" })
58+
@SuppressWarnings("DataFlowIssue")
5959
//tag::user_guide[]
6060
@AfterParameterizedClassInvocation
6161
static void afterInvocation(TextFile textFile) throws Exception {
@@ -66,7 +66,7 @@ static void afterInvocation(TextFile textFile) throws Exception {
6666
}
6767

6868
//end::user_guide[]
69-
@SuppressWarnings({ "DataFlowIssue", "NullAway" })
69+
@SuppressWarnings("DataFlowIssue")
7070
//tag::user_guide[]
7171
@Test
7272
void test() {

documentation/src/test/java/example/SecondCustomEngine.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId
4848
return new EngineDescriptor(uniqueId, "Second Custom Test Engine");
4949
}
5050

51+
//end::user_guide[]
52+
@SuppressWarnings("NullAway")
53+
//tag::user_guide[]
5154
@Override
5255
public void execute(ExecutionRequest request) {
5356
request.getEngineExecutionListener()

documentation/src/test/java/example/interceptor/SwingEdtInterceptor.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
// tag::user_guide[]
2424
public class SwingEdtInterceptor implements InvocationInterceptor {
2525

26+
//end::user_guide[]
27+
@SuppressWarnings("NullAway")
28+
//tag::user_guide[]
2629
@Override
2730
public void interceptTestMethod(Invocation<Void> invocation,
2831
ReflectiveInvocationContext<Method> invocationContext,

junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTimeout.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,15 @@ static void assertTimeout(Duration timeout, Executable executable) {
3636
assertTimeout(timeout, executable, (String) null);
3737
}
3838

39-
@SuppressWarnings("NullAway")
4039
static void assertTimeout(Duration timeout, Executable executable, @Nullable String message) {
41-
assertTimeout(timeout, () -> {
40+
AssertTimeout.<@Nullable Object> assertTimeout(timeout, () -> {
4241
executable.execute();
4342
return null;
4443
}, message);
4544
}
4645

47-
@SuppressWarnings("NullAway")
4846
static void assertTimeout(Duration timeout, Executable executable, Supplier<@Nullable String> messageSupplier) {
49-
assertTimeout(timeout, () -> {
47+
AssertTimeout.<@Nullable Object> assertTimeout(timeout, () -> {
5048
executable.execute();
5149
return null;
5250
}, messageSupplier);

junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/ExtensionContext.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,9 @@ default <V> V getOrDefault(Object key, Class<V> requiredType, V defaultValue) {
614614
* @see CloseableResource
615615
* @see AutoCloseable
616616
*/
617-
@SuppressWarnings({ "DataFlowIssue", "NullAway" })
618617
@API(status = STABLE, since = "5.1")
619-
default <V> V getOrComputeIfAbsent(Class<V> type) {
618+
@SuppressWarnings("NullAway")
619+
default <V> @Nullable V getOrComputeIfAbsent(Class<V> type) {
620620
return getOrComputeIfAbsent(type, ReflectionSupport::newInstance, type);
621621
}
622622

@@ -650,7 +650,7 @@ default <V> V getOrComputeIfAbsent(Class<V> type) {
650650
* @see CloseableResource
651651
* @see AutoCloseable
652652
*/
653-
<K, V> @Nullable Object getOrComputeIfAbsent(K key, Function<K, @Nullable V> defaultCreator);
653+
<K, V extends @Nullable Object> @Nullable Object getOrComputeIfAbsent(K key, Function<K, V> defaultCreator);
654654

655655
/**
656656
* Get the value of the specified required type that is stored under the
@@ -681,7 +681,8 @@ default <V> V getOrComputeIfAbsent(Class<V> type) {
681681
* @see CloseableResource
682682
* @see AutoCloseable
683683
*/
684-
<K, V> @Nullable V getOrComputeIfAbsent(K key, Function<K, @Nullable V> defaultCreator, Class<V> requiredType);
684+
<K, V extends @Nullable Object> @Nullable V getOrComputeIfAbsent(K key, Function<K, V> defaultCreator,
685+
Class<V> requiredType);
685686

686687
/**
687688
* Store a {@code value} for later retrieval under the supplied {@code key}.

junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
import org.junit.jupiter.engine.execution.DefaultTestInstances;
6262
import org.junit.jupiter.engine.execution.ExtensionContextSupplier;
6363
import org.junit.jupiter.engine.execution.InterceptingExecutableInvoker;
64-
import org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.ReflectiveInterceptorCall;
6564
import org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.ReflectiveInterceptorCall.VoidMethodInterceptorCall;
6665
import org.junit.jupiter.engine.execution.JupiterEngineExecutionContext;
6766
import org.junit.jupiter.engine.execution.TestInstancesProvider;
@@ -448,8 +447,8 @@ private void invokeBeforeAllMethods(JupiterEngineExecutionContext context) {
448447
for (Method method : requireLifecycleMethods().beforeAll) {
449448
throwableCollector.execute(() -> {
450449
try {
451-
executableInvoker.invoke(method, testInstance, extensionContext, registry,
452-
ReflectiveInterceptorCall.ofVoidMethod(InvocationInterceptor::interceptBeforeAllMethod));
450+
executableInvoker.invokeVoid(method, testInstance, extensionContext, registry,
451+
InvocationInterceptor::interceptBeforeAllMethod);
453452
}
454453
catch (Throwable throwable) {
455454
invokeBeforeAllMethodExecutionExceptionHandlers(registry, extensionContext, throwable);
@@ -476,8 +475,8 @@ private void invokeAfterAllMethods(JupiterEngineExecutionContext context) {
476475

477476
requireLifecycleMethods().afterAll.forEach(method -> throwableCollector.execute(() -> {
478477
try {
479-
executableInvoker.invoke(method, testInstance, extensionContext, registry,
480-
ReflectiveInterceptorCall.ofVoidMethod(InvocationInterceptor::interceptAfterAllMethod));
478+
executableInvoker.invokeVoid(method, testInstance, extensionContext, registry,
479+
InvocationInterceptor::interceptAfterAllMethod);
481480
}
482481
catch (Throwable throwable) {
483482
invokeAfterAllMethodExecutionExceptionHandlers(registry, extensionContext, throwable);
@@ -549,8 +548,7 @@ private void invokeMethodInExtensionContext(Method method, ExtensionContext cont
549548
Object target = testInstances.findInstance(getTestClass()).orElseThrow(
550549
() -> new JUnitException("Failed to find instance for method: " + method.toGenericString()));
551550

552-
executableInvoker.invoke(method, target, context, registry,
553-
ReflectiveInterceptorCall.ofVoidMethod(interceptorCall));
551+
executableInvoker.invokeVoid(method, target, context, registry, interceptorCall);
554552
}
555553

556554
private LifecycleMethods requireLifecycleMethods() {

junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/DynamicTestTestDescriptor.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,14 @@ public JupiterEngineExecutionContext execute(JupiterEngineExecutionContext conte
6565
requiredDynamicTest().getExecutable());
6666
ExtensionContext extensionContext = context.getExtensionContext();
6767
ExtensionRegistry extensionRegistry = context.getExtensionRegistry();
68-
interceptorChain.invoke(toInvocation(), extensionRegistry, InterceptorCall.ofVoid(
69-
(interceptor, wrappedInvocation) -> interceptor.interceptDynamicTest(wrappedInvocation,
70-
dynamicTestInvocationContext, extensionContext)));
68+
interceptorChain.<@Nullable Void> invoke(toInvocation(), extensionRegistry, InterceptorCall.ofVoid((
69+
InvocationInterceptor interceptor,
70+
InvocationInterceptor.Invocation<@Nullable Void> wrappedInvocation) -> interceptor.interceptDynamicTest(
71+
wrappedInvocation, dynamicTestInvocationContext, extensionContext)));
7172
return context;
7273
}
7374

74-
@SuppressWarnings("NullAway")
75-
private InvocationInterceptor.Invocation<Void> toInvocation() {
75+
private InvocationInterceptor.Invocation<@Nullable Void> toInvocation() {
7676
return () -> {
7777
requiredDynamicTest().getExecutable().execute();
7878
return null;

junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ExtensionUtils.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ static void registerExtensionsFromInstanceFields(ExtensionRegistrar registrar, C
139139
/**
140140
* @since 5.11
141141
*/
142+
@SuppressWarnings("NullAway")
142143
private static Extension readAndValidateExtensionFromField(Field field, @Nullable Object instance,
143144
List<Class<? extends Extension>> declarativeExtensionTypes) {
144145
Object value = tryToReadFieldValue(field, instance) //

junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ public class TestFactoryTestDescriptor extends TestMethodTestDescriptor implemen
5959
public static final String DYNAMIC_CONTAINER_SEGMENT_TYPE = "dynamic-container";
6060
public static final String DYNAMIC_TEST_SEGMENT_TYPE = "dynamic-test";
6161

62-
@SuppressWarnings("NullAway")
6362
private static final ReflectiveInterceptorCall<Method, @Nullable Object> interceptorCall = InvocationInterceptor::interceptTestFactoryMethod;
6463
private static final InterceptingExecutableInvoker executableInvoker = new InterceptingExecutableInvoker();
6564

@@ -112,8 +111,8 @@ protected void invokeTestMethod(JupiterEngineExecutionContext context, DynamicTe
112111

113112
context.getThrowableCollector().execute(() -> {
114113
Object instance = extensionContext.getRequiredTestInstance();
115-
Object testFactoryMethodResult = executableInvoker.invoke(getTestMethod(), instance, extensionContext,
116-
context.getExtensionRegistry(), interceptorCall);
114+
Object testFactoryMethodResult = executableInvoker.<@Nullable Object> invoke(getTestMethod(), instance,
115+
extensionContext, context.getExtensionRegistry(), interceptorCall);
117116
TestSource defaultTestSource = getSource().orElseThrow(
118117
() -> new JUnitException("Illegal state: TestSource must be present"));
119118
try (Stream<DynamicNode> dynamicNodeStream = toDynamicNodeStream(testFactoryMethodResult)) {

0 commit comments

Comments
 (0)