Skip to content

Commit

Permalink
Fix multiple issues in JodaTime to JavaTime migration recipe
Browse files Browse the repository at this point in the history
  • Loading branch information
amishra-u committed Dec 2, 2024
1 parent cd36280 commit 13b1307
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -42,6 +43,19 @@ public JodaTimeVisitor(JodaTimeRecipe.Accumulator acc, boolean safeMigration, Li
this.acc = acc;
this.safeMigration = safeMigration;
}

@Override
protected JavadocVisitor<ExecutionContext> getJavadocVisitor() {
return new JavadocVisitor<ExecutionContext>(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) {
Expand Down Expand Up @@ -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).<J>map(t -> t.apply(
updateCursor(m),
m.getCoordinates().replace(),
VarTemplates.getTemplateArgs(m))).orElse(multiVariable);
}

@Override
Expand Down Expand Up @@ -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).<J>map(t -> t.apply(
updateCursor(a),
a.getCoordinates().replace(),
varName,
a.getAssignment());
a.getAssignment())).orElse(assignment);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*;

Expand All @@ -37,9 +38,12 @@ public class VarTemplates {
}
};

public static JavaTemplate getTemplate(J.VariableDeclarations variable) {
public static Optional<JavaTemplate> 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 {
Expand All @@ -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<JavaTemplate> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Long> 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<Long> 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);
}
}
"""
)
);
}
}

0 comments on commit 13b1307

Please sign in to comment.