Skip to content

Commit 22d8d31

Browse files
committed
Enable NullAway in junit-jupiter-params
1 parent 08257cb commit 22d8d31

39 files changed

+247
-113
lines changed

junit-jupiter-params/junit-jupiter-params.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import junitbuild.extensions.javaModuleName
22

33
plugins {
4+
id("junitbuild.java-nullability-conventions")
45
id("junitbuild.kotlin-library-conventions")
56
id("junitbuild.shadow-conventions")
67
id("junitbuild.jmh-conventions")
@@ -15,6 +16,7 @@ dependencies {
1516
api(projects.junitJupiterApi)
1617

1718
compileOnlyApi(libs.apiguardian)
19+
compileOnly(libs.jspecify)
1820

1921
shadowed(libs.univocity.parsers)
2022

junit-jupiter-params/src/main/java/module-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
* @since 5.0
1515
*/
1616
module org.junit.jupiter.params {
17+
1718
requires static transitive org.apiguardian.api;
19+
requires static org.jspecify;
20+
1821
requires transitive org.junit.jupiter.api;
1922
requires transitive org.junit.platform.commons;
2023

junit-jupiter-params/src/main/java/org/junit/jupiter/params/AbstractParameterizedClassInvocationLifecycleMethodInvoker.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
package org.junit.jupiter.params;
1212

13+
import static java.util.Objects.requireNonNull;
14+
1315
import org.junit.jupiter.api.extension.ExecutableInvoker;
1416
import org.junit.jupiter.api.extension.ExtensionContext;
1517
import org.junit.jupiter.api.extension.ParameterContext;
@@ -52,9 +54,9 @@ public boolean supportsParameter(ParameterContext parameterContext, ExtensionCon
5254
@Override
5355
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
5456
throws ParameterResolutionException {
55-
return this.lifecycleMethod.parameterResolver //
57+
return requireNonNull(this.lifecycleMethod.parameterResolver //
5658
.resolve(parameterContext, extensionContext, this.arguments, this.invocationIndex,
57-
this.resolutionCache);
59+
this.resolutionCache));
5860
}
5961

6062
protected void invoke(ExtensionContext context) {

junit-jupiter-params/src/main/java/org/junit/jupiter/params/ArgumentCountValidator.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
package org.junit.jupiter.params;
1212

13+
import static java.util.Objects.requireNonNull;
14+
1315
import java.util.Arrays;
1416
import java.util.Optional;
1517

@@ -72,7 +74,7 @@ private ArgumentCountValidationMode getArgumentCountValidationModeConfiguration(
7274
String key = ARGUMENT_COUNT_VALIDATION_KEY;
7375
ArgumentCountValidationMode fallback = ArgumentCountValidationMode.NONE;
7476
ExtensionContext.Store store = getStore(extensionContext);
75-
return store.getOrComputeIfAbsent(key, __ -> {
77+
return requireNonNull(store.getOrComputeIfAbsent(key, __ -> {
7678
Optional<String> optionalConfigValue = extensionContext.getConfigurationParameter(key);
7779
if (optionalConfigValue.isPresent()) {
7880
String configValue = optionalConfigValue.get();
@@ -96,7 +98,7 @@ private ArgumentCountValidationMode getArgumentCountValidationModeConfiguration(
9698
else {
9799
return fallback;
98100
}
99-
}, ArgumentCountValidationMode.class);
101+
}, ArgumentCountValidationMode.class));
100102
}
101103

102104
private static String pluralize(int count, String singular, String plural) {

junit-jupiter-params/src/main/java/org/junit/jupiter/params/ArgumentSetLifecycleMethod.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import java.lang.reflect.Method;
1414

15+
import org.jspecify.annotations.Nullable;
1516
import org.junit.jupiter.api.extension.ExtensionContext;
1617
import org.junit.jupiter.api.extension.ParameterContext;
1718
import org.junit.platform.commons.JUnitException;
@@ -51,6 +52,7 @@ public Object resolve(ParameterContext parameterContext, ExtensionContext extens
5152

5253
boolean supports(ParameterContext parameterContext);
5354

55+
@Nullable
5456
Object resolve(ParameterContext parameterContext, ExtensionContext extensionContext,
5557
EvaluatedArgumentSet arguments, int invocationIndex, ResolutionCache resolutionCache);
5658

junit-jupiter-params/src/main/java/org/junit/jupiter/params/EvaluatedArgumentSet.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.function.Function;
1616
import java.util.function.IntUnaryOperator;
1717

18+
import org.jspecify.annotations.Nullable;
1819
import org.junit.jupiter.api.Named;
1920
import org.junit.jupiter.params.provider.Arguments;
2021
import org.junit.jupiter.params.provider.Arguments.ArgumentSet;
@@ -32,25 +33,29 @@
3233
class EvaluatedArgumentSet {
3334

3435
static EvaluatedArgumentSet allOf(Arguments arguments) {
36+
@Nullable
3537
Object[] all = arguments.get();
3638
return create(all, all, arguments);
3739
}
3840

3941
static EvaluatedArgumentSet of(Arguments arguments, IntUnaryOperator consumedLengthComputer) {
42+
@Nullable
4043
Object[] all = arguments.get();
44+
@Nullable
4145
Object[] consumed = dropSurplus(all, consumedLengthComputer.applyAsInt(all.length));
4246
return create(all, consumed, arguments);
4347
}
4448

45-
private static EvaluatedArgumentSet create(Object[] all, Object[] consumed, Arguments arguments) {
49+
private static EvaluatedArgumentSet create(@Nullable Object[] all, @Nullable Object[] consumed,
50+
Arguments arguments) {
4651
return new EvaluatedArgumentSet(all, consumed, determineName(arguments));
4752
}
4853

49-
private final Object[] all;
50-
private final Object[] consumed;
54+
private final @Nullable Object[] all;
55+
private final @Nullable Object[] consumed;
5156
private final Optional<String> name;
5257

53-
private EvaluatedArgumentSet(Object[] all, Object[] consumed, Optional<String> name) {
58+
private EvaluatedArgumentSet(@Nullable Object[] all, @Nullable Object[] consumed, Optional<String> name) {
5459
this.all = all;
5560
this.consumed = consumed;
5661
this.name = name;
@@ -60,6 +65,7 @@ int getTotalLength() {
6065
return this.all.length;
6166
}
6267

68+
@Nullable
6369
Object[] getAllPayloads() {
6470
return extractFromNamed(this.all, Named::getPayload);
6571
}
@@ -68,14 +74,17 @@ int getConsumedLength() {
6874
return this.consumed.length;
6975
}
7076

77+
@Nullable
7178
Object[] getConsumedNames() {
7279
return extractFromNamed(this.consumed, Named::getName);
7380
}
7481

82+
@Nullable
7583
Object[] getConsumedPayloads() {
7684
return extractFromNamed(this.consumed, Named::getPayload);
7785
}
7886

87+
@Nullable
7988
Object getConsumedPayload(int index) {
8089
return extractFromNamed(this.consumed[index], Named::getPayload);
8190
}
@@ -84,7 +93,7 @@ Optional<String> getName() {
8493
return this.name;
8594
}
8695

87-
private static Object[] dropSurplus(Object[] arguments, int newLength) {
96+
private static @Nullable Object[] dropSurplus(@Nullable Object[] arguments, int newLength) {
8897
Preconditions.condition(newLength <= arguments.length,
8998
() -> "New length %d must be less than or equal to the total length %d".formatted(newLength,
9099
arguments.length));
@@ -98,13 +107,15 @@ private static Optional<String> determineName(Arguments arguments) {
98107
return Optional.empty();
99108
}
100109

101-
private static Object[] extractFromNamed(Object[] arguments, Function<Named<?>, Object> mapper) {
110+
private static @Nullable Object[] extractFromNamed(@Nullable Object[] arguments,
111+
Function<Named<?>, @Nullable Object> mapper) {
102112
return Arrays.stream(arguments) //
103113
.map(argument -> extractFromNamed(argument, mapper)) //
104114
.toArray();
105115
}
106116

107-
private static Object extractFromNamed(Object argument, Function<Named<?>, Object> mapper) {
117+
@Nullable
118+
private static Object extractFromNamed(@Nullable Object argument, Function<Named<?>, @Nullable Object> mapper) {
108119
return argument instanceof Named<?> named ? mapper.apply(named) : argument;
109120
}
110121

junit-jupiter-params/src/main/java/org/junit/jupiter/params/ParameterizedClassExtension.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
package org.junit.jupiter.params;
1212

13+
import static java.util.Objects.requireNonNull;
1314
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
1415
import static org.junit.jupiter.params.ParameterizedClassContext.InjectionType.CONSTRUCTOR;
1516
import static org.junit.platform.commons.support.AnnotationSupport.findAnnotation;
@@ -124,8 +125,8 @@ private static ParameterizedClassContext createClassContext(ExtensionContext ext
124125
}
125126

126127
private ParameterizedClassContext getDeclarationContext(ExtensionContext extensionContext) {
127-
return getStore(extensionContext)//
128-
.get(DECLARATION_CONTEXT_KEY, ParameterizedClassContext.class);
128+
return requireNonNull(getStore(extensionContext)//
129+
.get(DECLARATION_CONTEXT_KEY, ParameterizedClassContext.class));
129130
}
130131

131132
private Store getStore(ExtensionContext context) {

junit-jupiter-params/src/main/java/org/junit/jupiter/params/ParameterizedInvocationContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.Arrays;
1616
import java.util.concurrent.atomic.AtomicInteger;
1717

18+
import org.jspecify.annotations.Nullable;
1819
import org.junit.jupiter.api.extension.ExtensionContext;
1920
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
2021
import org.junit.jupiter.params.aggregator.ArgumentsAccessor;
@@ -71,6 +72,7 @@ private void validateArgumentCount(ExtensionContext context) {
7172
private void storeParameterInfo(ExtensionContext context) {
7273
ParameterDeclarations declarations = this.declarationContext.getResolverFacade().getIndexedParameterDeclarations();
7374
ClassLoader classLoader = getClassLoader(this.declarationContext.getTestClass());
75+
@Nullable
7476
Object[] arguments = this.arguments.getConsumedPayloads();
7577
ArgumentsAccessor accessor = DefaultArgumentsAccessor.create(context, invocationIndex, classLoader, arguments);
7678
new DefaultParameterInfo(declarations, accessor).store(context);

junit-jupiter-params/src/main/java/org/junit/jupiter/params/ParameterizedInvocationNameFormatter.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
package org.junit.jupiter.params;
1212

13+
import static java.util.Objects.requireNonNull;
1314
import static java.util.stream.Collectors.joining;
1415
import static org.junit.jupiter.params.ParameterizedInvocationConstants.ARGUMENTS_PLACEHOLDER;
1516
import static org.junit.jupiter.params.ParameterizedInvocationConstants.ARGUMENTS_WITH_NAMES_PLACEHOLDER;
@@ -34,6 +35,7 @@
3435
import java.util.function.Function;
3536
import java.util.stream.IntStream;
3637

38+
import org.jspecify.annotations.Nullable;
3739
import org.junit.jupiter.api.extension.ExtensionConfigurationException;
3840
import org.junit.jupiter.api.extension.ExtensionContext;
3941
import org.junit.platform.commons.JUnitException;
@@ -130,6 +132,7 @@ private PartialFormatter[] parse(String pattern, String displayName,
130132
return result.toArray(new PartialFormatter[0]);
131133
}
132134

135+
@Nullable
133136
private static PlaceholderPosition findFirstPlaceholder(PartialFormatters formatters, String segment) {
134137
if (segment.length() < formatters.minimumPlaceholderLength) {
135138
return null;
@@ -210,10 +213,10 @@ private static class PlaceholderPosition {
210213
private static class ArgumentsContext {
211214

212215
private final int invocationIndex;
213-
private final Object[] consumedArguments;
216+
private final @Nullable Object[] consumedArguments;
214217
private final Optional<String> argumentSetName;
215218

216-
ArgumentsContext(int invocationIndex, Object[] consumedArguments, Optional<String> argumentSetName) {
219+
ArgumentsContext(int invocationIndex, @Nullable Object[] consumedArguments, Optional<String> argumentSetName) {
217220
this.invocationIndex = invocationIndex;
218221
this.consumedArguments = consumedArguments;
219222
this.argumentSetName = argumentSetName;
@@ -268,8 +271,9 @@ public synchronized void append(ArgumentsContext context, StringBuffer result) {
268271
this.messageFormat.format(makeReadable(context.consumedArguments), result, new FieldPosition(0));
269272
}
270273

271-
private Object[] makeReadable(Object[] arguments) {
274+
private @Nullable Object[] makeReadable(@Nullable Object[] arguments) {
272275
Format[] formats = messageFormat.getFormatsByArgumentIndex();
276+
@Nullable
273277
Object[] result = Arrays.copyOf(arguments, Math.min(arguments.length, formats.length), Object[].class);
274278
for (int i = 0; i < result.length; i++) {
275279
if (formats[i] == null) {
@@ -279,7 +283,8 @@ private Object[] makeReadable(Object[] arguments) {
279283
return result;
280284
}
281285

282-
private String truncateIfExceedsMaxLength(String argument) {
286+
@Nullable
287+
private String truncateIfExceedsMaxLength(@Nullable String argument) {
283288
if (argument != null && argument.length() > this.argumentMaxLength) {
284289
return argument.substring(0, this.argumentMaxLength - 1) + ELLIPSIS;
285290
}
@@ -316,7 +321,7 @@ void put(String placeholder, PartialFormatter formatter) {
316321
}
317322

318323
PartialFormatter get(String placeholder) {
319-
return formattersByPlaceholder.get(placeholder);
324+
return requireNonNull(formattersByPlaceholder.get(placeholder));
320325
}
321326

322327
Set<String> placeholders() {

junit-jupiter-params/src/main/java/org/junit/jupiter/params/ParameterizedInvocationParameterResolver.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import java.lang.reflect.Executable;
1414

15+
import org.jspecify.annotations.Nullable;
1516
import org.junit.jupiter.api.extension.ExtensionContext;
1617
import org.junit.jupiter.api.extension.ParameterContext;
1718
import org.junit.jupiter.api.extension.ParameterResolutionException;
@@ -50,6 +51,7 @@ public final boolean supportsParameter(ParameterContext parameterContext, Extens
5051
}
5152

5253
@Override
54+
@Nullable
5355
public final Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
5456
throws ParameterResolutionException {
5557

0 commit comments

Comments
 (0)