Skip to content

Commit 02e09d0

Browse files
authored
Annotate nullable array type parameters (#779)
- openrewrite/rewrite-migrate-java#934
1 parent 0f25051 commit 02e09d0

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

src/main/java/org/openrewrite/staticanalysis/AnnotateNullableParameters.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
import java.util.*;
3333

34+
import static java.util.Collections.singletonList;
35+
import static java.util.Comparator.comparing;
3436
import static java.util.stream.Collectors.toList;
3537

3638
@EqualsAndHashCode(callSuper = false)
@@ -110,7 +112,31 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration methodDecl
110112
String.format("package %s;public @interface %s {}", fullyQualifiedPackage, simpleName)))
111113
.build()
112114
.apply(new Cursor(getCursor(), vd),
113-
vd.getCoordinates().addAnnotation(Comparator.comparing(J.Annotation::getSimpleName)));
115+
vd.getCoordinates().addAnnotation(comparing(J.Annotation::getSimpleName)));
116+
117+
// For array types, move annotation from leading annotations to array brackets
118+
if (annotated.getTypeExpression() instanceof J.ArrayType) {
119+
// Find the annotation we just added
120+
J.Annotation nullableAnnotation = null;
121+
for (J.Annotation ann : annotated.getLeadingAnnotations()) {
122+
if (ann.getSimpleName().equals(simpleName)) {
123+
nullableAnnotation = ann;
124+
break;
125+
}
126+
}
127+
if (nullableAnnotation != null) {
128+
J.Annotation finalAnnotation = nullableAnnotation;
129+
J.ArrayType arrayType = (J.ArrayType) annotated.getTypeExpression();
130+
annotated = annotated.withLeadingAnnotations(ListUtils.map(annotated.getLeadingAnnotations(),
131+
a -> a == finalAnnotation ? null : a));
132+
arrayType = arrayType.withAnnotations(singletonList(finalAnnotation.withPrefix(Space.SINGLE_SPACE)));
133+
if (annotated.getLeadingAnnotations().isEmpty()) {
134+
arrayType = arrayType.withPrefix(Space.EMPTY);
135+
}
136+
annotated = annotated.withTypeExpression(arrayType);
137+
}
138+
}
139+
114140
doAfterVisit(ShortenFullyQualifiedTypeReferences.modifyOnly(annotated));
115141
doAfterVisit(new MoveFieldAnnotationToType(fullyQualifiedName).getVisitor());
116142
return annotated.withModifiers(ListUtils.mapFirst(annotated.getModifiers(), first -> first.withPrefix(Space.SINGLE_SPACE)));

src/test/java/org/openrewrite/staticanalysis/AnnotateNullableParametersTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.junit.jupiter.params.provider.CsvSource;
2222
import org.junit.jupiter.params.provider.ValueSource;
2323
import org.openrewrite.DocumentExample;
24+
import org.openrewrite.Issue;
2425
import org.openrewrite.java.JavaParser;
2526
import org.openrewrite.test.RecipeSpec;
2627
import org.openrewrite.test.RewriteTest;
@@ -256,6 +257,36 @@ public void bar(@Nullable final String name) {
256257
)
257258
);
258259
}
260+
261+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/934")
262+
@Test
263+
void arrayParameter() {
264+
rewriteRun(
265+
//language=java
266+
java(
267+
"""
268+
public class ArrayProcessor {
269+
public void processItems(String[] items) {
270+
if (items == null) {
271+
return;
272+
}
273+
}
274+
}
275+
""",
276+
"""
277+
import org.jspecify.annotations.Nullable;
278+
279+
public class ArrayProcessor {
280+
public void processItems(String @Nullable[] items) {
281+
if (items == null) {
282+
return;
283+
}
284+
}
285+
}
286+
"""
287+
)
288+
);
289+
}
259290
}
260291

261292
@Nested

0 commit comments

Comments
 (0)