diff --git a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java b/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java index 647dac37b7..be5e5652f3 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java @@ -19,6 +19,7 @@ import org.jspecify.annotations.Nullable; import org.openrewrite.ExecutionContext; import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.JavadocVisitor; import org.openrewrite.java.migrate.joda.templates.AllTemplates; import org.openrewrite.java.migrate.joda.templates.MethodTemplate; import org.openrewrite.java.migrate.joda.templates.TimeClassMap; @@ -43,6 +44,19 @@ public JodaTimeVisitor(JodaTimeRecipe.Accumulator acc, boolean safeMigration, Li this.safeMigration = safeMigration; } + @Override + protected JavadocVisitor getJavadocVisitor() { + return new JavadocVisitor(this) { + /** + * Do not visit the method referenced from the Javadoc, may cause recipe to fail. + */ + @Override + public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx) { + return reference; + } + }; + } + @Override public @NonNull J visitCompilationUnit(@NonNull J.CompilationUnit cu, @NonNull ExecutionContext ctx) { maybeRemoveImport(JODA_DATE_TIME); @@ -70,17 +84,17 @@ public JodaTimeVisitor(JodaTimeRecipe.Accumulator acc, boolean safeMigration, Li @Override public @NonNull J visitVariableDeclarations(@NonNull J.VariableDeclarations multiVariable, @NonNull ExecutionContext ctx) { - if (!multiVariable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { + if (multiVariable.getTypeExpression() == null || !multiVariable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { return super.visitVariableDeclarations(multiVariable, ctx); } if (multiVariable.getVariables().stream().anyMatch(acc.getUnsafeVars()::contains)) { return multiVariable; } - multiVariable = (J.VariableDeclarations) super.visitVariableDeclarations(multiVariable, ctx); - return VarTemplates.getTemplate(multiVariable).apply( - updateCursor(multiVariable), - multiVariable.getCoordinates().replace(), - VarTemplates.getTemplateArgs(multiVariable)); + J.VariableDeclarations m = (J.VariableDeclarations) super.visitVariableDeclarations(multiVariable, ctx); + return VarTemplates.getTemplate(multiVariable).map(t -> t.apply( + updateCursor(m), + m.getCoordinates().replace(), + VarTemplates.getTemplateArgs(m))).orElse(multiVariable); } @Override @@ -111,11 +125,11 @@ public JodaTimeVisitor(JodaTimeRecipe.Accumulator acc, boolean safeMigration, Li if (!mayBeVar.isPresent() || acc.getUnsafeVars().contains(mayBeVar.get())) { return assignment; } - return VarTemplates.getTemplate(a).apply( + return VarTemplates.getTemplate(assignment).map(t -> t.apply( updateCursor(a), a.getCoordinates().replace(), varName, - a.getAssignment()); + a.getAssignment())).orElse(assignment); } @Override diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/VarTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/VarTemplates.java index c85b30293f..d555492a33 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/VarTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/VarTemplates.java @@ -21,6 +21,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Optional; import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; @@ -37,9 +38,12 @@ public class VarTemplates { } }; - public static JavaTemplate getTemplate(J.VariableDeclarations variable) { + public static Optional getTemplate(J.VariableDeclarations variable) { JavaType.Class type = (JavaType.Class) variable.getTypeExpression().getType(); String typeName = JodaToJavaTimeType.get(type.getFullyQualifiedName()); + if (typeName == null) { + return Optional.empty(); // unhandled type + } StringBuilder template = new StringBuilder(); String varName; try { @@ -60,19 +64,21 @@ public static JavaTemplate getTemplate(J.VariableDeclarations variable) { template.append(")}"); } } - return JavaTemplate.builder(template.toString()) + return Optional.of(JavaTemplate.builder(template.toString()) .imports(typeName) - .build(); + .build()); } - public static JavaTemplate getTemplate(J.Assignment assignment) { + public static Optional getTemplate(J.Assignment assignment) { JavaType.Class type = (JavaType.Class) assignment.getAssignment().getType(); JavaType.Class varType = (JavaType.Class) assignment.getVariable().getType(); String typeName = JodaToJavaTimeType.get(type.getFullyQualifiedName()); String varTypeName = JodaToJavaTimeType.get(varType.getFullyQualifiedName()); + if (typeName == null || varTypeName == null) { + return Optional.empty(); // unhandled type + } String template = "#{any(" + varTypeName + ")} = #{any(" + typeName + ")}"; - return JavaTemplate.builder(template) - .build(); + return Optional.of(JavaTemplate.builder(template).build()); } public static Object[] getTemplateArgs(J.VariableDeclarations variable) { diff --git a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeVisitorTest.java b/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeVisitorTest.java index 86fecef8ac..71118e3a88 100644 --- a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeVisitorTest.java +++ b/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeVisitorTest.java @@ -733,4 +733,64 @@ public void foo() { ) ); } + + @Test + void lambdaVarDeclaration() { + //language=java + rewriteRun( + java( + """ + import org.joda.time.DateTime; + import java.util.List; + import java.util.ArrayList; + + class A { + public void foo() { + List list = new ArrayList<>(); + list.add(100L); + list.add(200L); + list.forEach(millis -> { + System.out.println(new DateTime().withMillis(millis)); + }); + } + } + """, + """ + import java.util.List; + import java.time.Instant; + import java.time.ZonedDateTime; + import java.util.ArrayList; + + class A { + public void foo() { + List list = new ArrayList<>(); + list.add(100L); + list.add(200L); + list.forEach(millis -> { + System.out.println(ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), ZonedDateTime.now().getZone())); + }); + } + } + """ + ) + ); + } + + @Test + void unhandledVarDeclaration() { + //language=java + rewriteRun( + java( + """ + import org.joda.time.Interval; + + class A { + public void foo(Interval interval) { + interval = new Interval(100, 50); + } + } + """ + ) + ); + } }