Skip to content

Commit

Permalink
fix array component primitive type (#257)
Browse files Browse the repository at this point in the history
This PR fixes a bug in handling type arguments where arrays with primitive component types were incorrectly processed. The issue stemmed from an assumption that type arguments could not be primitives. However, we missed the case where an array used as a type argument can have a primitive component type.

To resolve this, the relevant method in TypeArgChangeVisitor is now overridden to account for arrays with primitive component types used as type arguments. This ensures that the appropriate changes are applied consistently.
  • Loading branch information
nimakarimipour authored Nov 7, 2024
1 parent d0f1f45 commit afda6c6
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.type.ArrayType;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.ast.type.PrimitiveType;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.ast.type.WildcardType;
import com.github.javaparser.ast.visitor.GenericVisitorWithDefaults;
import com.google.common.collect.ImmutableList;
Expand Down Expand Up @@ -58,15 +60,36 @@ public TypeArgumentChangeVisitor(ImmutableList<Integer> index, AnnotationExpr an
this.annotationExpr = annotationExpr;
}

/**
* Applies the change on the given type.
*
* @param type the type to apply the change on.
* @param change the change to apply.
* @return the set of modifications to apply on the type.
*/
private Set<Modification> applyOnType(Type type, TypeUseAnnotationChange change) {
Modification onType = change.computeTextModificationOnType(type, annotationExpr);
if (onType != null) {
return Set.of(onType);
} else {
// Unable to apply the change on the type.
return Collections.emptySet();
}
}

/**
* Checks if the index reached to base.
*
* @return true if the index is at base, false otherwise.
*/
private boolean isAtBase() {
return index.size() == 1 && index.getFirst() == 0;
}

@Override
public Set<Modification> visit(ClassOrInterfaceType type, TypeUseAnnotationChange change) {
if (index.size() == 1 && index.getFirst() == 0) {
Modification onType = change.computeTextModificationOnType(type, annotationExpr);
if (onType != null) {
return Set.of(onType);
} else {
return Collections.emptySet();
}
if (isAtBase()) {
return applyOnType(type, change);
}
if (type.getTypeArguments().isEmpty() || this.index.isEmpty()) {
return Collections.emptySet();
Expand All @@ -80,11 +103,8 @@ public Set<Modification> visit(ClassOrInterfaceType type, TypeUseAnnotationChang

@Override
public Set<Modification> visit(ArrayType type, TypeUseAnnotationChange change) {
if (index.size() == 1 && index.getFirst() == 0) {
Modification onType = change.computeTextModificationOnType(type, annotationExpr);
if (onType != null) {
return Set.of(onType);
}
if (isAtBase()) {
return applyOnType(type, change);
}
// if current index is 1, the process component type
if (!index.isEmpty()) {
Expand All @@ -98,12 +118,23 @@ public Set<Modification> visit(ArrayType type, TypeUseAnnotationChange change) {

@Override
public Set<Modification> visit(WildcardType type, TypeUseAnnotationChange change) {
Modification onType = change.computeTextModificationOnType(type, annotationExpr);
if (onType != null) {
return Set.of(onType);
} else {
return Collections.emptySet();
return applyOnType(type, change);
}

/**
* This method is called when the visitor visits a primitive type. This is necessary because the
* component type of array may be a primitive type.
*
* @param type the primitive type
* @param change the change to apply
* @return the set of modifications to apply on the type.
*/
@Override
public Set<Modification> visit(PrimitiveType type, TypeUseAnnotationChange change) {
if (isAtBase()) {
return applyOnType(type, change);
}
return Collections.emptySet();
}

/** This will be called by every node visit method that is not overridden. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -821,4 +821,28 @@ public void nullableArrayDeletionOnReference() {
"javax.annotation.Nullable"))
.start();
}

@Test
public void nullableArrayAdditionOnComponentWithArrayOfPrimitiveType() {
injectorTestHelper
.addInput(
"Foo.java",
"package test;",
"import javax.annotation.Nullable;",
"public class Foo {",
" List<char[]> h3 = new ArrayList<>();",
"}")
.expectOutput(
"package test;",
"import javax.annotation.Nullable;",
"public class Foo {",
" List<@Nullable char[]> h3 = new ArrayList<>();",
"}")
.addChanges(
new AddTypeUseMarkerAnnotation(
new OnField("Foo.java", "test.Foo", Collections.singleton("h3")),
"javax.annotation.Nullable",
ImmutableList.of(ImmutableList.of(1, 1, 0))))
.start();
}
}

0 comments on commit afda6c6

Please sign in to comment.