From 725e9d0668e59ee0978e4e4b399359fee82cf6c7 Mon Sep 17 00:00:00 2001 From: Niels de Bruin Date: Wed, 23 Oct 2024 17:11:50 +0200 Subject: [PATCH 01/11] Transfer arguments --- ...oveDoublyAnnotatedCodehausAnnotations.java | 27 ++-- ...rUsingArgumentFromCodehausToFasterXML.java | 117 ++++++++++++++++++ ...ngArgumentFromCodehausToFasterXMLTest.java | 93 ++++++++++++++ 3 files changed, 225 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java create mode 100644 src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java diff --git a/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java b/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java index 6bfa2fa..6c94c71 100644 --- a/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java +++ b/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java @@ -25,8 +25,9 @@ import org.openrewrite.java.service.AnnotationService; import org.openrewrite.java.tree.J; -import java.util.HashSet; -import java.util.Set; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class RemoveDoublyAnnotatedCodehausAnnotations extends Recipe { @@ -52,17 +53,18 @@ public TreeVisitor getVisitor() { public J preVisit(@NonNull J tree, ExecutionContext ctx) { stopAfterPreVisit(); - Set annotationsToRemove = new FindDoublyAnnotatedVisitor().reduce(tree, new HashSet<>()); - AnnotationMatcher matcher = new AnnotationMatcher( + // Map from codehaus -> fasterxml annotation + Map doubleAnnotated = new FindDoublyAnnotatedVisitor().reduce(tree, new HashMap<>()); + + AnnotationMatcher removeCodehausMatcher = new AnnotationMatcher( // ignored in practice, as we only match annotations previously found just above "@org.codehaus.jackson.map.annotate.JsonSerialize", true) { @Override public boolean matches(J.Annotation annotation) { - return annotationsToRemove.contains(annotation); + return doubleAnnotated.containsKey(annotation); } }; - - doAfterVisit(new RemoveAnnotationVisitor(matcher)); + doAfterVisit(new RemoveAnnotationVisitor(removeCodehausMatcher)); maybeRemoveImport("org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.*"); maybeRemoveImport("org.codehaus.jackson.map.annotate.JsonSerialize.Typing.*"); doAfterVisit(new ShortenFullyQualifiedTypeReferences().getVisitor()); @@ -71,15 +73,16 @@ public boolean matches(J.Annotation annotation) { }); } - private static class FindDoublyAnnotatedVisitor extends JavaIsoVisitor> { + static class FindDoublyAnnotatedVisitor extends JavaIsoVisitor> { + @Override - public J.Annotation visitAnnotation(J.Annotation annotation, Set doublyAnnotated) { + public J.Annotation visitAnnotation(J.Annotation annotation, HashMap doublyAnnotated) { J.Annotation a = super.visitAnnotation(annotation, doublyAnnotated); - if (MATCHER_CODEHAUS.matches(annotation) && service(AnnotationService.class).matches(getCursor().getParentOrThrow(), MATCHER_FASTERXML)) { - doublyAnnotated.add(annotation); + if (MATCHER_CODEHAUS.matches(annotation)) { + List doublyAnnotatedList = service(AnnotationService.class).getAllAnnotations(getCursor().getParentOrThrow()); + doublyAnnotatedList.stream().filter(MATCHER_FASTERXML::matches).findFirst().ifPresent(fasterxml -> doublyAnnotated.put(annotation, fasterxml)); } return a; } } - } diff --git a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java new file mode 100644 index 0000000..5ce088b --- /dev/null +++ b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java @@ -0,0 +1,117 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.jackson.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.jackson.codehaus; + +import lombok.RequiredArgsConstructor; +import org.jspecify.annotations.NonNull; +import org.openrewrite.*; +import org.openrewrite.java.JavaIsoVisitor; +import org.openrewrite.java.search.UsesType; +import org.openrewrite.java.tree.Expression; +import org.openrewrite.java.tree.J; + +import java.util.*; + +public class TransferUsingArgumentFromCodehausToFasterXML extends Recipe { + + @Override + public @NlsRewrite.DisplayName String getDisplayName() { + return "Transfer using argument from Codehaus to FasterXML"; + } + + @Override + public @NlsRewrite.Description String getDescription() { + return "Transfer the using argument from Codehaus to FasterXML if it was not set before. " + + "If the `using` argument was set already, it will not be transferred."; + } + + + @Override + public TreeVisitor getVisitor() { + return Preconditions.check(Preconditions.and( + new UsesType<>("org.codehaus.jackson.map.annotate.JsonSerialize", false), + new UsesType<>("com.fasterxml.jackson.databind.annotation.JsonSerialize", false)), + new JavaIsoVisitor() { + @Override + public J preVisit(@NonNull J tree, ExecutionContext ctx) { + stopAfterPreVisit(); + + // Map from codehaus -> fasterxml annotation + Map doubleAnnotated = new RemoveDoublyAnnotatedCodehausAnnotations + .FindDoublyAnnotatedVisitor().reduce(tree, new HashMap<>()); + + doAfterVisit(new TransferUsingVisitor(mapToArgumentExpression(doubleAnnotated))); + return tree; + } + }); + } + + + private Map mapToArgumentExpression(Map doubleAnnotated) { + // Map from fasterxml -> value of "using=..." in codehaus annotation + Map mapToArgument = new HashMap<>(); + doubleAnnotated.forEach((key, value) -> { + if (key.getArguments() != null || key.getArguments().isEmpty()) { + key.getArguments().forEach(arg -> { + if (arg instanceof J.Assignment) { + J.Assignment assign = (J.Assignment) arg; + J.Identifier varId = (J.Identifier) assign.getVariable(); + if ("using".equals(varId.getSimpleName())) { + mapToArgument.put(value, arg); + } + } + }); + } + }); + return mapToArgument; + } + + @RequiredArgsConstructor + private static class TransferUsingVisitor extends JavaIsoVisitor { + + private final Map mapToArgument; + + @Override + public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ctx) { + Expression e = mapToArgument.get(annotation); + if (e != null) { + List arguments = annotation.getArguments(); + if (arguments == null) { + arguments = new ArrayList<>(); + } else if (!arguments.isEmpty()) { + Optional expression = arguments.stream().filter(arg -> { + if (arg instanceof J.Assignment) { + J.Assignment assign = (J.Assignment) arg; + J.Identifier varId = (J.Identifier) assign.getVariable(); + return "using".equals(varId.getSimpleName()); + } + return false; + }).findFirst(); + + if (expression.isPresent()) { + return annotation; + } + } + + arguments.add(e); + J.Annotation a = annotation.withArguments(arguments); + a = autoFormat(a, ctx); + return a; + } + return annotation; + } + } +} diff --git a/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java b/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java new file mode 100644 index 0000000..946f66f --- /dev/null +++ b/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java @@ -0,0 +1,93 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.jackson.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.jackson.codehaus; + +import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +@SuppressWarnings("DefaultAnnotationParam") +class TransferUsingArgumentFromCodehausToFasterXMLTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec + .recipe(new TransferUsingArgumentFromCodehausToFasterXML()) + .parser(JavaParser.fromJavaVersion().classpath(JavaParser.runtimeClasspath())); + } + + @DocumentExample + @Test + void shouldTransferArgument() { + rewriteRun( + //language=java + java( + """ + import org.codehaus.jackson.map.JsonSerializer.None; + import org.codehaus.jackson.map.annotate.JsonSerialize; + import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; + + @JsonSerialize(include = NON_NULL, using = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize + class Test { + @JsonSerialize(include = NON_NULL, using = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize + private String first; + } + """, + """ + import org.codehaus.jackson.map.JsonSerializer.None; + import org.codehaus.jackson.map.annotate.JsonSerialize; + import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; + + @JsonSerialize(include = NON_NULL, using = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = None.class) + class Test { + @JsonSerialize(include = NON_NULL, using = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = None.class) + private String first; + } + """ + ) + ); + } + + @Test + void shouldNotTransferArgument() { + rewriteRun( + //language=java + java( + """ + import org.codehaus.jackson.map.JsonSerializer.None; + import org.codehaus.jackson.map.annotate.JsonSerialize; + import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; + + @JsonSerialize(include = NON_NULL, using = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = com.fasterxml.jackson.databind.JsonSerializer.None.class) + class Test { + @JsonSerialize(include = NON_NULL, using = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = com.fasterxml.jackson.databind.JsonSerializer.None.class) + private String first; + } + """ + ) + ); + } +} From 9a49630bc4bc8680f0b78de9a6120bb9873f7d3e Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 24 Oct 2024 11:25:10 +0200 Subject: [PATCH 02/11] Skip format by manipulating prefix --- ...oveDoublyAnnotatedCodehausAnnotations.java | 15 ++++-- ...rUsingArgumentFromCodehausToFasterXML.java | 52 +++++++++++-------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java b/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java index 6c94c71..c5b073c 100644 --- a/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java +++ b/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java @@ -31,8 +31,8 @@ public class RemoveDoublyAnnotatedCodehausAnnotations extends Recipe { - private static final AnnotationMatcher MATCHER_FASTERXML = new AnnotationMatcher("@com.fasterxml.jackson.databind.annotation.JsonSerialize", true); private static final AnnotationMatcher MATCHER_CODEHAUS = new AnnotationMatcher("@org.codehaus.jackson.map.annotate.JsonSerialize", true); + private static final AnnotationMatcher MATCHER_FASTERXML = new AnnotationMatcher("@com.fasterxml.jackson.databind.annotation.JsonSerialize", true); @Override public String getDisplayName() { @@ -73,14 +73,19 @@ public boolean matches(J.Annotation annotation) { }); } - static class FindDoublyAnnotatedVisitor extends JavaIsoVisitor> { + static class FindDoublyAnnotatedVisitor extends JavaIsoVisitor> { @Override - public J.Annotation visitAnnotation(J.Annotation annotation, HashMap doublyAnnotated) { + public J.Annotation visitAnnotation(J.Annotation annotation, Map doublyAnnotated) { J.Annotation a = super.visitAnnotation(annotation, doublyAnnotated); if (MATCHER_CODEHAUS.matches(annotation)) { - List doublyAnnotatedList = service(AnnotationService.class).getAllAnnotations(getCursor().getParentOrThrow()); - doublyAnnotatedList.stream().filter(MATCHER_FASTERXML::matches).findFirst().ifPresent(fasterxml -> doublyAnnotated.put(annotation, fasterxml)); + // Find sibling fasterXMl annotation + service(AnnotationService.class) + .getAllAnnotations(getCursor().getParentOrThrow()) + .stream() + .filter(MATCHER_FASTERXML::matches) + .findFirst() + .ifPresent(fasterxml -> doublyAnnotated.put(annotation, fasterxml)); } return a; } diff --git a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java index 5ce088b..b048ba3 100644 --- a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java +++ b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java @@ -17,25 +17,32 @@ import lombok.RequiredArgsConstructor; import org.jspecify.annotations.NonNull; -import org.openrewrite.*; +import org.openrewrite.ExecutionContext; +import org.openrewrite.Preconditions; +import org.openrewrite.Recipe; +import org.openrewrite.TreeVisitor; import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.search.UsesType; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.Space; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class TransferUsingArgumentFromCodehausToFasterXML extends Recipe { @Override - public @NlsRewrite.DisplayName String getDisplayName() { + public String getDisplayName() { return "Transfer using argument from Codehaus to FasterXML"; } @Override - public @NlsRewrite.Description String getDescription() { + public String getDescription() { return "Transfer the using argument from Codehaus to FasterXML if it was not set before. " + - "If the `using` argument was set already, it will not be transferred."; + "If the `using` argument was set already, it will not be transferred."; } @@ -89,27 +96,26 @@ public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ct Expression e = mapToArgument.get(annotation); if (e != null) { List arguments = annotation.getArguments(); - if (arguments == null) { - arguments = new ArrayList<>(); - } else if (!arguments.isEmpty()) { - Optional expression = arguments.stream().filter(arg -> { - if (arg instanceof J.Assignment) { - J.Assignment assign = (J.Assignment) arg; - J.Identifier varId = (J.Identifier) assign.getVariable(); - return "using".equals(varId.getSimpleName()); - } - return false; - }).findFirst(); - - if (expression.isPresent()) { - return annotation; - } + if (arguments == null || arguments.isEmpty() || arguments.get(0) instanceof J.Empty) { + return annotation.withArguments(Collections.singletonList(e.withPrefix(Space.EMPTY))); } + boolean alreadyUsing = arguments.stream() + .filter(arg -> { + if (arg instanceof J.Assignment) { + J.Assignment assign = (J.Assignment) arg; + J.Identifier varId = (J.Identifier) assign.getVariable(); + return "using".equals(varId.getSimpleName()); + } + return false; + }) + .findFirst() + .isPresent(); + if (alreadyUsing) { + return annotation; + } arguments.add(e); - J.Annotation a = annotation.withArguments(arguments); - a = autoFormat(a, ctx); - return a; + return annotation.withArguments(arguments); } return annotation; } From b5fab130a8a7a90774582b1eda0ec0b58217bab6 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 24 Oct 2024 11:33:23 +0200 Subject: [PATCH 03/11] Slight polish --- ...rUsingArgumentFromCodehausToFasterXML.java | 41 ++++++++----------- .../rewrite/codehaus-to-fasterxml.yml | 1 + 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java index b048ba3..9e9c3a6 100644 --- a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java +++ b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java @@ -22,6 +22,7 @@ import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; import org.openrewrite.java.JavaIsoVisitor; +import org.openrewrite.java.jackson.codehaus.RemoveDoublyAnnotatedCodehausAnnotations.FindDoublyAnnotatedVisitor; import org.openrewrite.java.search.UsesType; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; @@ -57,17 +58,15 @@ public J preVisit(@NonNull J tree, ExecutionContext ctx) { stopAfterPreVisit(); // Map from codehaus -> fasterxml annotation - Map doubleAnnotated = new RemoveDoublyAnnotatedCodehausAnnotations - .FindDoublyAnnotatedVisitor().reduce(tree, new HashMap<>()); - - doAfterVisit(new TransferUsingVisitor(mapToArgumentExpression(doubleAnnotated))); + Map doubleAnnotated = new FindDoublyAnnotatedVisitor().reduce(tree, new HashMap<>()); + Map fasterXmlToUsingExpression = mapToArgumentExpression(doubleAnnotated); + doAfterVisit(new TransferUsingVisitor(fasterXmlToUsingExpression)); return tree; } }); } - - private Map mapToArgumentExpression(Map doubleAnnotated) { + private static Map mapToArgumentExpression(Map doubleAnnotated) { // Map from fasterxml -> value of "using=..." in codehaus annotation Map mapToArgument = new HashMap<>(); doubleAnnotated.forEach((key, value) -> { @@ -89,33 +88,29 @@ private Map mapToArgumentExpression(Map { - private final Map mapToArgument; + private final Map fasterXmlToUsingExpression; @Override public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ctx) { - Expression e = mapToArgument.get(annotation); + Expression e = fasterXmlToUsingExpression.get(annotation); if (e != null) { List arguments = annotation.getArguments(); if (arguments == null || arguments.isEmpty() || arguments.get(0) instanceof J.Empty) { return annotation.withArguments(Collections.singletonList(e.withPrefix(Space.EMPTY))); } - boolean alreadyUsing = arguments.stream() - .filter(arg -> { - if (arg instanceof J.Assignment) { - J.Assignment assign = (J.Assignment) arg; - J.Identifier varId = (J.Identifier) assign.getVariable(); - return "using".equals(varId.getSimpleName()); - } - return false; - }) - .findFirst() - .isPresent(); - if (alreadyUsing) { - return annotation; + boolean notAlreadyUsing = arguments.stream().noneMatch(arg -> { + if (arg instanceof J.Assignment) { + J.Assignment assign = (J.Assignment) arg; + J.Identifier varId = (J.Identifier) assign.getVariable(); + return "using".equals(varId.getSimpleName()); + } + return false; + }); + if (notAlreadyUsing) { + arguments.add(e); + return annotation.withArguments(arguments); } - arguments.add(e); - return annotation.withArguments(arguments); } return annotation; } diff --git a/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml b/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml index 48de917..7badd3b 100644 --- a/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml +++ b/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml @@ -22,6 +22,7 @@ description: >- In Jackson 2, the package and dependency coordinates moved from Codehaus to FasterXML. recipeList: - org.openrewrite.java.jackson.codehaus.RemoveDoublyAnnotatedCodehausAnnotations + - org.openrewrite.java.jackson.codehaus.TransferUsingArgumentFromCodehausToFasterXMLTest - org.openrewrite.java.jackson.CodehausClassesToFasterXML - org.openrewrite.java.jackson.codehaus.CodehausDependencyToFasterXML: version: 2.x From dd18d98cecc9aa5c5bbbc26350c407bfdc3802bb Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 24 Oct 2024 11:34:02 +0200 Subject: [PATCH 04/11] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java b/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java index c5b073c..e600708 100644 --- a/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java +++ b/src/main/java/org/openrewrite/java/jackson/codehaus/RemoveDoublyAnnotatedCodehausAnnotations.java @@ -26,7 +26,6 @@ import org.openrewrite.java.tree.J; import java.util.HashMap; -import java.util.List; import java.util.Map; public class RemoveDoublyAnnotatedCodehausAnnotations extends Recipe { From fde7ea85e4a01538884ea486c0608ab389eeeba6 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 24 Oct 2024 11:35:29 +0200 Subject: [PATCH 05/11] Name the second test after why it should not change --- .../TransferUsingArgumentFromCodehausToFasterXMLTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java b/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java index 946f66f..254b02f 100644 --- a/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java +++ b/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java @@ -70,7 +70,7 @@ class Test { } @Test - void shouldNotTransferArgument() { + void doNotOverwriteExistingUsing() { rewriteRun( //language=java java( From 736fce00e97139dd7a30f5aa529d6bb0c3e575d2 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 24 Oct 2024 11:47:38 +0200 Subject: [PATCH 06/11] Also convert known serializer packages over to databind --- .../resources/META-INF/rewrite/codehaus-to-fasterxml.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml b/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml index 7badd3b..d978be3 100644 --- a/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml +++ b/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml @@ -60,3 +60,11 @@ recipeList: oldPackageName: org.codehaus.jackson.annotate newPackageName: com.fasterxml.jackson.annotation recursive: true + - org.openrewrite.java.ChangePackage: + oldPackageName: org.codehaus.jackson.map.ext + newPackageName: com.fasterxml.jackson.databind.ext + recursive: true + - org.openrewrite.java.ChangePackage: + oldPackageName: org.codehaus.jackson.map.ser + newPackageName: com.fasterxml.jackson.databind.ser + recursive: true From 70ab8c7e054c240c0d302f23c63214079c267129 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 24 Oct 2024 11:49:47 +0200 Subject: [PATCH 07/11] Fix recipe name --- src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml b/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml index d978be3..8aa0293 100644 --- a/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml +++ b/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml @@ -22,7 +22,7 @@ description: >- In Jackson 2, the package and dependency coordinates moved from Codehaus to FasterXML. recipeList: - org.openrewrite.java.jackson.codehaus.RemoveDoublyAnnotatedCodehausAnnotations - - org.openrewrite.java.jackson.codehaus.TransferUsingArgumentFromCodehausToFasterXMLTest + - org.openrewrite.java.jackson.codehaus.TransferUsingArgumentFromCodehausToFasterXML - org.openrewrite.java.jackson.CodehausClassesToFasterXML - org.openrewrite.java.jackson.codehaus.CodehausDependencyToFasterXML: version: 2.x From 906931641e115b5c753d329d9d4371bc5d9f2fb6 Mon Sep 17 00:00:00 2001 From: Niels de Bruin Date: Thu, 24 Oct 2024 14:40:55 +0200 Subject: [PATCH 08/11] Add functionality to also transfer other arguments --- ...rUsingArgumentFromCodehausToFasterXML.java | 22 +++- ...ngArgumentFromCodehausToFasterXMLTest.java | 120 +++++++++++++++--- 2 files changed, 119 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java index 9e9c3a6..d3556df 100644 --- a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java +++ b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java @@ -59,14 +59,25 @@ public J preVisit(@NonNull J tree, ExecutionContext ctx) { // Map from codehaus -> fasterxml annotation Map doubleAnnotated = new FindDoublyAnnotatedVisitor().reduce(tree, new HashMap<>()); - Map fasterXmlToUsingExpression = mapToArgumentExpression(doubleAnnotated); - doAfterVisit(new TransferUsingVisitor(fasterXmlToUsingExpression)); + + Map fasterXmlToUsingExpression = mapToArgumentExpression(doubleAnnotated, "using"); + doAfterVisit(new TransferUsingVisitor(fasterXmlToUsingExpression, "using")); + + Map fasterXmlToContentUsingExpression = mapToArgumentExpression(doubleAnnotated, "contentUsing"); + doAfterVisit(new TransferUsingVisitor(fasterXmlToContentUsingExpression, "contentUsing")); + + Map fasterXmlToKeyUsingExpression = mapToArgumentExpression(doubleAnnotated, "keyUsing"); + doAfterVisit(new TransferUsingVisitor(fasterXmlToKeyUsingExpression, "keyUsing")); + + Map fasterXmlToNullsUsingExpression = mapToArgumentExpression(doubleAnnotated, "nullUsing"); + doAfterVisit(new TransferUsingVisitor(fasterXmlToNullsUsingExpression, "nullUsing")); + return tree; } }); } - private static Map mapToArgumentExpression(Map doubleAnnotated) { + private static Map mapToArgumentExpression(Map doubleAnnotated, String argumentName) { // Map from fasterxml -> value of "using=..." in codehaus annotation Map mapToArgument = new HashMap<>(); doubleAnnotated.forEach((key, value) -> { @@ -75,7 +86,7 @@ private static Map mapToArgumentExpression(Map mapToArgumentExpression(Map { private final Map fasterXmlToUsingExpression; + private final String argumentName; @Override public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ctx) { @@ -103,7 +115,7 @@ public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ct if (arg instanceof J.Assignment) { J.Assignment assign = (J.Assignment) arg; J.Identifier varId = (J.Identifier) assign.getVariable(); - return "using".equals(varId.getSimpleName()); + return argumentName.equals(varId.getSimpleName()); } return false; }); diff --git a/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java b/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java index 254b02f..9d1ecc7 100644 --- a/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java +++ b/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java @@ -15,7 +15,9 @@ */ package org.openrewrite.java.jackson.codehaus; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; import org.openrewrite.DocumentExample; import org.openrewrite.java.JavaParser; import org.openrewrite.test.RecipeSpec; @@ -34,8 +36,11 @@ public void defaults(RecipeSpec spec) { } @DocumentExample - @Test - void shouldTransferArgument() { + @ParameterizedTest + @ValueSource( + strings = {"using", "contentUsing", "keyUsing", "nullUsing"} + ) + void shouldTransferArgument(String argumentName) { rewriteRun( //language=java java( @@ -44,33 +49,36 @@ void shouldTransferArgument() { import org.codehaus.jackson.map.annotate.JsonSerialize; import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; - @JsonSerialize(include = NON_NULL, using = None.class) + @JsonSerialize(include = NON_NULL, %1$s = None.class) @com.fasterxml.jackson.databind.annotation.JsonSerialize class Test { - @JsonSerialize(include = NON_NULL, using = None.class) + @JsonSerialize(include = NON_NULL, %1$s = None.class) @com.fasterxml.jackson.databind.annotation.JsonSerialize private String first; } - """, + """.formatted(argumentName), """ import org.codehaus.jackson.map.JsonSerializer.None; import org.codehaus.jackson.map.annotate.JsonSerialize; import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; - @JsonSerialize(include = NON_NULL, using = None.class) - @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = None.class) + @JsonSerialize(include = NON_NULL, %1$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(%1$s = None.class) class Test { - @JsonSerialize(include = NON_NULL, using = None.class) - @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = None.class) + @JsonSerialize(include = NON_NULL, %1$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(%1$s = None.class) private String first; } - """ + """.formatted(argumentName) ) ); } - @Test - void doNotOverwriteExistingUsing() { + @ParameterizedTest + @CsvSource( + {"using,contentUsing", "keyUsing,nullUsing"} + ) + void shouldTransferArgumentMultiArguments(String firstArg, String secondArg) { rewriteRun( //language=java java( @@ -79,14 +87,90 @@ void doNotOverwriteExistingUsing() { import org.codehaus.jackson.map.annotate.JsonSerialize; import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; - @JsonSerialize(include = NON_NULL, using = None.class) - @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = com.fasterxml.jackson.databind.JsonSerializer.None.class) + @JsonSerialize(include = NON_NULL, %1$s = None.class, %2$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize + class Test { + @JsonSerialize(include = NON_NULL, %1$s = None.class, %2$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize + private String first; + } + """.formatted(firstArg, secondArg), + """ + import org.codehaus.jackson.map.JsonSerializer.None; + import org.codehaus.jackson.map.annotate.JsonSerialize; + import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; + + @JsonSerialize(include = NON_NULL, %1$s = None.class, %2$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(%1$s = None.class, %2$s = None.class) + class Test { + @JsonSerialize(include = NON_NULL, %1$s = None.class, %2$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(%1$s = None.class, %2$s = None.class) + private String first; + } + """.formatted(firstArg, secondArg) + ) + ); + } + + @ParameterizedTest + @ValueSource( + strings = {"using", "contentUsing", "keyUsing", "nullUsing"} + ) + void doNotOverwriteExistingUsing(String argumentName) { + rewriteRun( + //language=java + java( + """ + import org.codehaus.jackson.map.JsonSerializer.None; + import org.codehaus.jackson.map.annotate.JsonSerialize; + import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; + + @JsonSerialize(include = NON_NULL, %1$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(%1$s = com.fasterxml.jackson.databind.JsonSerializer.None.class) + class Test { + @JsonSerialize(include = NON_NULL, %1$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(%1$s = com.fasterxml.jackson.databind.JsonSerializer.None.class) + private String first; + } + """.formatted(argumentName) + ) + ); + } + + @ParameterizedTest + @CsvSource( + {"using,contentUsing", "keyUsing,nullUsing"} + ) + void shouldTransferArgumentSome(String firstArg, String secondArg) { + rewriteRun( + //language=java + java( + """ + import org.codehaus.jackson.map.JsonSerializer.None; + import org.codehaus.jackson.map.annotate.JsonSerialize; + import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; + + @JsonSerialize(include = NON_NULL, %1$s = None.class, %2$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize + class Test { + @JsonSerialize(include = NON_NULL, %1$s = None.class, %2$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(%1$s = com.fasterxml.jackson.databind.JsonSerializer.None.class) + private String first; + } + """.formatted(firstArg, secondArg), + """ + import org.codehaus.jackson.map.JsonSerializer.None; + import org.codehaus.jackson.map.annotate.JsonSerialize; + import static org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL; + + @JsonSerialize(include = NON_NULL, %1$s = None.class, %2$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(%1$s = None.class, %2$s = None.class) class Test { - @JsonSerialize(include = NON_NULL, using = None.class) - @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = com.fasterxml.jackson.databind.JsonSerializer.None.class) + @JsonSerialize(include = NON_NULL, %1$s = None.class, %2$s = None.class) + @com.fasterxml.jackson.databind.annotation.JsonSerialize(%1$s = com.fasterxml.jackson.databind.JsonSerializer.None.class, %2$s = None.class) private String first; } - """ + """.formatted(firstArg, secondArg) ) ); } From 4dba8b56e937ae1dea0e2672ee4e260d15062f04 Mon Sep 17 00:00:00 2001 From: Niels de Bruin Date: Thu, 24 Oct 2024 14:54:49 +0200 Subject: [PATCH 09/11] Polish code --- ...lizeArgumentsFromCodehausToFasterXML.java} | 29 +++++++++---------- .../rewrite/codehaus-to-fasterxml.yml | 2 +- ...ArgumentsFromCodehausToFasterXMLTest.java} | 4 +-- 3 files changed, 16 insertions(+), 19 deletions(-) rename src/main/java/org/openrewrite/java/jackson/codehaus/{TransferUsingArgumentFromCodehausToFasterXML.java => TransferJsonSerializeArgumentsFromCodehausToFasterXML.java} (77%) rename src/test/java/org/openrewrite/java/jackson/codehaus/{TransferUsingArgumentFromCodehausToFasterXMLTest.java => TransferJsonSerializeArgumentsFromCodehausToFasterXMLTest.java} (97%) diff --git a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java similarity index 77% rename from src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java rename to src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java index d3556df..c080d3c 100644 --- a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXML.java +++ b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java @@ -33,20 +33,19 @@ import java.util.List; import java.util.Map; -public class TransferUsingArgumentFromCodehausToFasterXML extends Recipe { +public class TransferJsonSerializeArgumentsFromCodehausToFasterXML extends Recipe { @Override public String getDisplayName() { - return "Transfer using argument from Codehaus to FasterXML"; + return "Transfer @JsonSerialize arguments from Codehaus to FasterXML"; } @Override public String getDescription() { - return "Transfer the using argument from Codehaus to FasterXML if it was not set before. " + - "If the `using` argument was set already, it will not be transferred."; + return "Transfer @JsonSerialize annotation arguments (using, contentUsing, keyUsing, nullUsing) from Codehaus " + + "to FasterXML. If the argument was set already, it will not be transferred."; } - @Override public TreeVisitor getVisitor() { return Preconditions.check(Preconditions.and( @@ -60,20 +59,18 @@ public J preVisit(@NonNull J tree, ExecutionContext ctx) { // Map from codehaus -> fasterxml annotation Map doubleAnnotated = new FindDoublyAnnotatedVisitor().reduce(tree, new HashMap<>()); - Map fasterXmlToUsingExpression = mapToArgumentExpression(doubleAnnotated, "using"); - doAfterVisit(new TransferUsingVisitor(fasterXmlToUsingExpression, "using")); - - Map fasterXmlToContentUsingExpression = mapToArgumentExpression(doubleAnnotated, "contentUsing"); - doAfterVisit(new TransferUsingVisitor(fasterXmlToContentUsingExpression, "contentUsing")); - - Map fasterXmlToKeyUsingExpression = mapToArgumentExpression(doubleAnnotated, "keyUsing"); - doAfterVisit(new TransferUsingVisitor(fasterXmlToKeyUsingExpression, "keyUsing")); - - Map fasterXmlToNullsUsingExpression = mapToArgumentExpression(doubleAnnotated, "nullUsing"); - doAfterVisit(new TransferUsingVisitor(fasterXmlToNullsUsingExpression, "nullUsing")); + transferArgument(doubleAnnotated, "using"); + transferArgument(doubleAnnotated, "contentUsing"); + transferArgument(doubleAnnotated, "keyUsing"); + transferArgument(doubleAnnotated, "nullUsing"); return tree; } + + private void transferArgument(Map doubleAnnotated, String argumentName) { + Map argumentExpressionMap = mapToArgumentExpression(doubleAnnotated, argumentName); + doAfterVisit(new TransferUsingVisitor(argumentExpressionMap, argumentName)); + } }); } diff --git a/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml b/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml index 8aa0293..c0da7f6 100644 --- a/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml +++ b/src/main/resources/META-INF/rewrite/codehaus-to-fasterxml.yml @@ -22,7 +22,7 @@ description: >- In Jackson 2, the package and dependency coordinates moved from Codehaus to FasterXML. recipeList: - org.openrewrite.java.jackson.codehaus.RemoveDoublyAnnotatedCodehausAnnotations - - org.openrewrite.java.jackson.codehaus.TransferUsingArgumentFromCodehausToFasterXML + - org.openrewrite.java.jackson.codehaus.TransferJsonSerializeArgumentsFromCodehausToFasterXML - org.openrewrite.java.jackson.CodehausClassesToFasterXML - org.openrewrite.java.jackson.codehaus.CodehausDependencyToFasterXML: version: 2.x diff --git a/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java b/src/test/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXMLTest.java similarity index 97% rename from src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java rename to src/test/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXMLTest.java index 9d1ecc7..1fe6a94 100644 --- a/src/test/java/org/openrewrite/java/jackson/codehaus/TransferUsingArgumentFromCodehausToFasterXMLTest.java +++ b/src/test/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXMLTest.java @@ -26,12 +26,12 @@ import static org.openrewrite.java.Assertions.java; @SuppressWarnings("DefaultAnnotationParam") -class TransferUsingArgumentFromCodehausToFasterXMLTest implements RewriteTest { +class TransferJsonSerializeArgumentsFromCodehausToFasterXMLTest implements RewriteTest { @Override public void defaults(RecipeSpec spec) { spec - .recipe(new TransferUsingArgumentFromCodehausToFasterXML()) + .recipe(new TransferJsonSerializeArgumentsFromCodehausToFasterXML()) .parser(JavaParser.fromJavaVersion().classpath(JavaParser.runtimeClasspath())); } From cfb95b39a25085178cd9913ccd2072313f547b84 Mon Sep 17 00:00:00 2001 From: Niels de Bruin Date: Thu, 24 Oct 2024 14:57:02 +0200 Subject: [PATCH 10/11] Rename TransferUsingVisitor to TransferArgumentsVisitor --- ...TransferJsonSerializeArgumentsFromCodehausToFasterXML.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java index c080d3c..5951fd1 100644 --- a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java +++ b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java @@ -69,7 +69,7 @@ public J preVisit(@NonNull J tree, ExecutionContext ctx) { private void transferArgument(Map doubleAnnotated, String argumentName) { Map argumentExpressionMap = mapToArgumentExpression(doubleAnnotated, argumentName); - doAfterVisit(new TransferUsingVisitor(argumentExpressionMap, argumentName)); + doAfterVisit(new TransferArgumentsVisitor(argumentExpressionMap, argumentName)); } }); } @@ -94,7 +94,7 @@ private static Map mapToArgumentExpression(Map { + private static class TransferArgumentsVisitor extends JavaIsoVisitor { private final Map fasterXmlToUsingExpression; private final String argumentName; From d9b39b005c13837402186affda40268a0f796917 Mon Sep 17 00:00:00 2001 From: Niels de Bruin Date: Thu, 24 Oct 2024 18:23:05 +0200 Subject: [PATCH 11/11] Move arguments to arr --- ...ferJsonSerializeArgumentsFromCodehausToFasterXML.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java index 5951fd1..262d37c 100644 --- a/src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java +++ b/src/main/java/org/openrewrite/java/jackson/codehaus/TransferJsonSerializeArgumentsFromCodehausToFasterXML.java @@ -35,6 +35,8 @@ public class TransferJsonSerializeArgumentsFromCodehausToFasterXML extends Recipe { + private static final String[] TRANSFERABLE_ARGUMENTS = {"using", "contentUsing", "keyUsing", "nullUsing"}; + @Override public String getDisplayName() { return "Transfer @JsonSerialize arguments from Codehaus to FasterXML"; @@ -59,10 +61,9 @@ public J preVisit(@NonNull J tree, ExecutionContext ctx) { // Map from codehaus -> fasterxml annotation Map doubleAnnotated = new FindDoublyAnnotatedVisitor().reduce(tree, new HashMap<>()); - transferArgument(doubleAnnotated, "using"); - transferArgument(doubleAnnotated, "contentUsing"); - transferArgument(doubleAnnotated, "keyUsing"); - transferArgument(doubleAnnotated, "nullUsing"); + for (String argumentName : TRANSFERABLE_ARGUMENTS) { + transferArgument(doubleAnnotated, argumentName); + } return tree; }