Skip to content

Commit

Permalink
added the option to add, replace or remove arrays in annotation attri…
Browse files Browse the repository at this point in the history
…butes (#4446)

Co-authored-by: marcel-gepardec <[email protected]>
Co-authored-by: Tim te Beek <[email protected]>
  • Loading branch information
3 people authored Oct 11, 2024
1 parent 00e4792 commit 76e5692
Show file tree
Hide file tree
Showing 2 changed files with 232 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -492,4 +492,180 @@ void foo() {
)
);
}

@Test
void arrayInAnnotationAttribute() {
rewriteRun(
spec -> spec.recipe(new AddOrUpdateAnnotationAttribute(
"org.example.Foo",
"array",
"newTest",
false)),
java(
"""
package org.example;
public @interface Foo {
String[] array() default {};
}
"""
),
java(
"""
import org.example.Foo;
@Foo(array = {"oldTest"})
public class A {
}
""",
"""
import org.example.Foo;
@Foo(array = {"newTest"})
public class A {
}
"""
)
);
}

@Test
void arrayInputMoreThanOneInAnnotationAttribute() {
rewriteRun(
spec -> spec.recipe(new AddOrUpdateAnnotationAttribute(
"org.example.Foo",
"array",
"newTest1,newTest2",
false)),
java(
"""
package org.example;
public @interface Foo {
String[] array() default {};
}
"""
),
java(
"""
import org.example.Foo;
@Foo(array = {"oldTest"})
public class A {
}
""",
"""
import org.example.Foo;
@Foo(array = {"newTest1", "newTest2"})
public class A {
}
"""
)
);
}

@Test
void addArrayInputInAnnotationAttribute() {
rewriteRun(
spec -> spec.recipe(new AddOrUpdateAnnotationAttribute(
"org.example.Foo",
"array",
"newTest1,newTest2",
false)),
java(
"""
package org.example;
public @interface Foo {
String[] array() default {};
}
"""
),
java(
"""
import org.example.Foo;
@Foo
public class A {
}
""",
"""
import org.example.Foo;
@Foo(array = {"newTest1", "newTest2"})
public class A {
}
"""
)
);
}

@Test
void removeArrayInputInAnnotationAttribute() {
rewriteRun(
spec -> spec.recipe(new AddOrUpdateAnnotationAttribute(
"org.example.Foo",
"array",
null,
null)),
java(
"""
package org.example;
public @interface Foo {
String[] array() default {};
}
"""
),
java(
"""
import org.example.Foo;
@Foo(array = {"newTest1", "newTest2"})
public class A {
}
""",
"""
import org.example.Foo;
@Foo
public class A {
}
"""
)
);
}

@Test
void addOtherAttributeInArrayAnnotation() {
rewriteRun(
spec -> spec.recipe(new AddOrUpdateAnnotationAttribute(
"org.example.Foo",
"string",
"test",
null)),
java(
"""
package org.example;
public @interface Foo {
String[] array() default {};
String string() default "";
}
"""
),
java(
"""
import org.example.Foo;
@Foo(array = {"newTest1", "newTest2"})
public class A {
}
""",
"""
import org.example.Foo;
@Foo(string = "test", array = {"newTest1", "newTest2"})
public class A {
}
"""
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaType;
import org.openrewrite.java.tree.TypeUtils;
import org.openrewrite.marker.Markers;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@Value
@EqualsAndHashCode(callSuper = false)
Expand Down Expand Up @@ -88,10 +92,18 @@ public J.Annotation visitAnnotation(J.Annotation a, ExecutionContext ctx) {
.build()
.apply(getCursor(), a.getCoordinates().replaceArguments(), newAttributeValue);
} else {
String newAttributeValueResult = newAttributeValue;
if (((JavaType.FullyQualified) Objects.requireNonNull(a.getAnnotationType().getType())).getMethods().stream().anyMatch(method -> method.getReturnType().toString().equals("java.lang.String[]"))) {
String attributeValueCleanedUp = attributeValue.replaceAll("\\s+","").replaceAll("[\\s+{}\"]","");
List<String> attributeList = Arrays.asList(attributeValueCleanedUp.contains(",") ? attributeValueCleanedUp.split(",") : new String[]{attributeValueCleanedUp});
newAttributeValueResult = attributeList.stream()
.map(String::valueOf)
.collect(Collectors.joining("\", \"", "{\"", "\"}"));
}
return JavaTemplate.builder("#{} = #{}")
.contextSensitive()
.build()
.apply(getCursor(), a.getCoordinates().replaceArguments(), attributeName, newAttributeValue);
.apply(getCursor(), a.getCoordinates().replaceArguments(), attributeName, newAttributeValueResult);
}
} else {
// First assume the value exists amongst the arguments and attempt to update it
Expand All @@ -105,14 +117,52 @@ public J.Annotation visitAnnotation(J.Annotation a, ExecutionContext ctx) {
return it;
}
foundOrSetAttributeWithDesiredValue.set(true);
J.Literal value = (J.Literal) as.getAssignment();

if (newAttributeValue == null) {
return null;
}
if (newAttributeValue.equals(value.getValueSource()) || Boolean.TRUE.equals(addOnly)) {
return it;

if (as.getAssignment() instanceof J.NewArray){
List<Expression> jLiteralList = ((J.NewArray) as.getAssignment()).getInitializer();
String attributeValueCleanedUp = attributeValue.replaceAll("\\s+","").replaceAll("[\\s+{}\"]","");
List<String> attributeList = Arrays.asList(attributeValueCleanedUp.contains(",") ? attributeValueCleanedUp.split(",") : new String[]{attributeValueCleanedUp});
int m = 0;
for (int i = 0; i< Objects.requireNonNull(jLiteralList).size(); i++){
if (i >= attributeList.size()){
jLiteralList.remove(i);
i--;
continue;
}

String newAttributeListValue = maybeQuoteStringArgument(attributeName, attributeList.get(i), finalA);
if (jLiteralList.size() == i+1){
m = i+1;
}

if (newAttributeListValue != null && newAttributeListValue.equals(((J.Literal) jLiteralList.get(i)).getValueSource()) || Boolean.TRUE.equals(addOnly)) {
continue;
}

jLiteralList.set(i, ((J.Literal) jLiteralList.get(i)).withValue(newAttributeListValue).withValueSource(newAttributeListValue).withPrefix(jLiteralList.get(i).getPrefix()));
}
if (jLiteralList.size() < attributeList.size() || Boolean.TRUE.equals(addOnly)){
if (Boolean.TRUE.equals(addOnly)){
m = 0;
}
for (int j = m; j < attributeList.size(); j++){
String newAttributeListValue = maybeQuoteStringArgument(attributeName, attributeList.get(j), finalA);
jLiteralList.add(j, new J.Literal(Tree.randomId(), jLiteralList.get(j-1).getPrefix(), Markers.EMPTY, newAttributeListValue, newAttributeListValue, null, JavaType.Primitive.String));
}
}

return as.withAssignment(((J.NewArray) as.getAssignment()).withInitializer(jLiteralList));
} else {
J.Literal value = (J.Literal) as.getAssignment();
if (newAttributeValue.equals(value.getValueSource()) || Boolean.TRUE.equals(addOnly)) {
return it;
}
return as.withAssignment(value.withValue(newAttributeValue).withValueSource(newAttributeValue));
}
return as.withAssignment(value.withValue(newAttributeValue).withValueSource(newAttributeValue));
} else if (it instanceof J.Literal) {
// The only way anything except an assignment can appear is if there's an implicit assignment to "value"
if (attributeName == null || "value".equals(attributeName)) {
Expand Down Expand Up @@ -164,6 +214,7 @@ public J.Annotation visitAnnotation(J.Annotation a, ExecutionContext ctx) {
a = a.withArguments(newArgs);
}
if (foundOrSetAttributeWithDesiredValue.get()) {
a = autoFormat(a, ctx);
return a;
}
// There was no existing value to update, so add a new value into the argument list
Expand Down

0 comments on commit 76e5692

Please sign in to comment.