diff --git a/build.gradle.kts b/build.gradle.kts index 0da963c0cd..d8b5f48297 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -61,8 +61,6 @@ dependencies { testImplementation("org.assertj:assertj-core:latest.release") testImplementation("com.google.errorprone:error_prone_annotations:latest.release") - testImplementation("joda-time:joda-time:2.12.3") - testImplementation("org.threeten:threeten-extra:1.8.0") testRuntimeOnly("com.fasterxml.jackson.datatype:jackson-datatype-jsr353") testRuntimeOnly("com.fasterxml.jackson.core:jackson-core") diff --git a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeFlowSpec.java b/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeFlowSpec.java deleted file mode 100644 index ffeb680545..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeFlowSpec.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -import lombok.NonNull; -import org.openrewrite.analysis.dataflow.DataFlowNode; -import org.openrewrite.analysis.dataflow.DataFlowSpec; -import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.JavaType; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_CLASS_PATTERN; - -class JodaTimeFlowSpec extends DataFlowSpec { - - @Override - public boolean isSource(@NonNull DataFlowNode srcNode) { - Object value = srcNode.getCursor().getParentTreeCursor().getValue(); - - if (value instanceof J.Assignment && ((J.Assignment) value).getVariable() instanceof J.Identifier) { - return isJodaType(((J.Assignment) value).getVariable().getType()); - } - - if (value instanceof J.VariableDeclarations.NamedVariable) { - return isJodaType(((J.VariableDeclarations.NamedVariable) value).getType()); - } - - if (value instanceof J.VariableDeclarations) { - if (srcNode.getCursor().getParentTreeCursor().getParentTreeCursor().getValue() instanceof J.MethodDeclaration) { - return isJodaType(((J.VariableDeclarations) value).getType()); - } - } - return false; - } - - @Override - public boolean isSink(@NonNull DataFlowNode sinkNode) { - Object value = sinkNode.getCursor().getValue(); - Object parent = sinkNode.getCursor().getParentTreeCursor().getValue(); - if (parent instanceof J.MethodInvocation) { - J.MethodInvocation method = (J.MethodInvocation) parent; - return (method.getSelect() != null && method.getSelect().equals(value)) || - method.getArguments().stream().anyMatch(a -> a.equals(value)); - } - return parent instanceof J.VariableDeclarations.NamedVariable || - parent instanceof J.NewClass || - parent instanceof J.Assignment || - parent instanceof J.Return; - } - - static boolean isJodaType(JavaType type) { - if (!(type instanceof JavaType.Class)) { - return false; - } - return type.isAssignableFrom(JODA_CLASS_PATTERN); - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeRecipe.java b/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeRecipe.java deleted file mode 100644 index 7bb2571067..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeRecipe.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -import lombok.Getter; -import org.jspecify.annotations.Nullable; -import org.openrewrite.ExecutionContext; -import org.openrewrite.Preconditions; -import org.openrewrite.ScanningRecipe; -import org.openrewrite.TreeVisitor; -import org.openrewrite.java.search.UsesType; -import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.J.VariableDeclarations.NamedVariable; -import org.openrewrite.java.tree.JavaType; - -import java.util.*; - -import static java.util.Collections.emptyList; - -public class JodaTimeRecipe extends ScanningRecipe { - @Override - public String getDisplayName() { - return "Migrate Joda-Time to Java time"; - } - - @Override - public String getDescription() { - return "Prefer the Java standard library over third-party usage of Joda Time."; - } - - @Override - public Accumulator getInitialValue(ExecutionContext ctx) { - return new Accumulator(); - } - - @Override - public TreeVisitor getScanner(Accumulator acc) { - return new JodaTimeScanner(acc); - } - - @Override - public TreeVisitor getVisitor(Accumulator acc) { - JodaTimeVisitor jodaTimeVisitor = new JodaTimeVisitor(acc, true, new LinkedList<>()); - return Preconditions.check(new UsesType<>("org.joda.time.*", true), jodaTimeVisitor); - } - - @Getter - public static class Accumulator { - private final Set unsafeVars = new HashSet<>(); - private final Map safeMethodMap = new HashMap<>(); - private final VarTable varTable = new VarTable(); - } - - static class VarTable { - private final Map> vars = new HashMap<>(); - - public void addVars(J.MethodDeclaration methodDeclaration) { - JavaType type = methodDeclaration.getMethodType(); - assert type != null; - methodDeclaration.getParameters().forEach(p -> { - if (!(p instanceof J.VariableDeclarations)) { - return; - } - J.VariableDeclarations.NamedVariable namedVariable = ((J.VariableDeclarations) p).getVariables().get(0); - vars.computeIfAbsent(type, k -> new ArrayList<>()).add(namedVariable); - }); - } - - public @Nullable NamedVariable getVarByName(@Nullable JavaType declaringType, String varName) { - return vars.getOrDefault(declaringType, emptyList()).stream() - .filter(v -> v.getSimpleName().equals(varName)) - .findFirst() // there should be only one variable with the same name - .orElse(null); - } - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeScanner.java b/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeScanner.java deleted file mode 100644 index e636dc915c..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeScanner.java +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -import fj.data.Option; -import lombok.Getter; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import lombok.Value; -import org.jspecify.annotations.Nullable; -import org.openrewrite.Cursor; -import org.openrewrite.ExecutionContext; -import org.openrewrite.analysis.dataflow.Dataflow; -import org.openrewrite.analysis.dataflow.analysis.SinkFlowSummary; -import org.openrewrite.java.JavaIsoVisitor; -import org.openrewrite.java.JavadocVisitor; -import org.openrewrite.java.tree.*; -import org.openrewrite.java.tree.J.VariableDeclarations.NamedVariable; - -import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; - -import static java.util.Collections.emptyList; -import static java.util.Collections.emptySet; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_CLASS_PATTERN; - -class JodaTimeScanner extends ScopeAwareVisitor { - - @Getter - private final JodaTimeRecipe.Accumulator acc; - - private final Map> varDependencies = new HashMap<>(); - private final Map> unsafeVarsByType = new HashMap<>(); - private final Map> methodReferencedVars = new HashMap<>(); - private final Map> methodUnresolvedReferencedVars = new HashMap<>(); - - public JodaTimeScanner(JodaTimeRecipe.Accumulator acc) { - super(new LinkedList<>()); - this.acc = acc; - } - - @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 J visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) { - super.visitCompilationUnit(cu, ctx); - Set allReachable = new HashSet<>(); - for (NamedVariable var : acc.getUnsafeVars()) { - dfs(var, allReachable); - } - acc.getUnsafeVars().addAll(allReachable); - - Set unsafeMethods = new HashSet<>(); - acc.getSafeMethodMap().forEach((method, isSafe) -> { - if (!isSafe) { - unsafeMethods.add(method); - return; - } - Set intersection = new HashSet<>(methodReferencedVars.getOrDefault(method, emptySet())); - intersection.retainAll(acc.getUnsafeVars()); - if (!intersection.isEmpty()) { - unsafeMethods.add(method); - } - }); - for (JavaType.Method method : unsafeMethods) { - acc.getSafeMethodMap().put(method, false); - acc.getUnsafeVars().addAll(methodReferencedVars.getOrDefault(method, emptySet())); - } - return cu; - } - - @Override - public J visitVariable(NamedVariable variable, ExecutionContext ctx) { - if (variable.getType() == null || !variable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return super.visitVariable(variable, ctx); - } - // TODO: handle class variables - if (isClassVar(variable)) { - acc.getUnsafeVars().add(variable); - return variable; - } - variable = (NamedVariable) super.visitVariable(variable, ctx); - - if (!variable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return variable; - } - boolean isMethodParam = getCursor().getParentTreeCursor() // VariableDeclaration - .getParentTreeCursor() // MethodDeclaration - .getValue() instanceof J.MethodDeclaration; - Cursor cursor = null; - if (isMethodParam) { - cursor = getCursor(); - } else if (variable.getInitializer() != null) { - cursor = new Cursor(getCursor(), variable.getInitializer()); - } - if (cursor == null) { - return variable; - } - List sinks = findSinks(cursor); - - Cursor currentScope = getCurrentScope(); - new AddSafeCheckMarker(sinks).visit(currentScope.getValue(), ctx, currentScope.getParentOrThrow()); - processMarkersOnExpression(sinks, variable); - return variable; - } - - @Override - public J visitAssignment(J.Assignment assignment, ExecutionContext ctx) { - Expression var = assignment.getVariable(); - // not joda expr or not local variable - if (!isJodaExpr(var) || !(var instanceof J.Identifier)) { - return super.visitAssignment(assignment, ctx); - } - J.Identifier ident = (J.Identifier) var; - Optional mayBeVar = findVarInScope(ident.getSimpleName()); - if (!mayBeVar.isPresent()) { - return super.visitAssignment(assignment, ctx); - } - NamedVariable variable = mayBeVar.get(); - Cursor varScope = findScope(variable); - List sinks = findSinks(new Cursor(getCursor(), assignment.getAssignment())); - new AddSafeCheckMarker(sinks).visit(varScope.getValue(), ctx, varScope.getParentOrThrow()); - processMarkersOnExpression(sinks, variable); - return super.visitAssignment(assignment, ctx); - } - - @Override - public J visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext ctx) { - acc.getVarTable().addVars(method); - unsafeVarsByType.getOrDefault(method.getMethodType(), emptySet()).forEach(varName -> { - NamedVariable var = acc.getVarTable().getVarByName(method.getMethodType(), varName); - if (var != null) { // var can only be null if method is not correctly type attributed - acc.getUnsafeVars().add(var); - } - }); - Set unresolvedVars = methodUnresolvedReferencedVars.remove(method.getMethodType()); - if (unresolvedVars != null) { - unresolvedVars.forEach(var -> { - NamedVariable namedVar = acc.getVarTable().getVarByName(var.getDeclaringType(), var.getVarName()); - if (namedVar != null) { - methodReferencedVars.computeIfAbsent(method.getMethodType(), k -> new HashSet<>()).add(namedVar); - } - }); - } - return super.visitMethodDeclaration(method, ctx); - } - - @Override - public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { - if (!isJodaExpr(method) || method.getMethodType().getDeclaringType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return super.visitMethodInvocation(method, ctx); - } - Cursor boundary = findBoundaryCursorForJodaExpr(getCursor()); - J j = new JodaTimeVisitor(new JodaTimeRecipe.Accumulator(), false, scopes) - .visit(boundary.getValue(), ctx, boundary.getParentTreeCursor()); - - boolean isSafe = j != boundary.getValue(); - acc.getSafeMethodMap().compute(method.getMethodType(), (k, v) -> v == null ? isSafe : v && isSafe); - J parent = boundary.getParentTreeCursor().getValue(); - if (parent instanceof NamedVariable) { - methodReferencedVars.computeIfAbsent(method.getMethodType(), k -> new HashSet<>()) - .add((NamedVariable) parent); - } - if (parent instanceof J.Assignment) { - J.Assignment assignment = (J.Assignment) parent; - if (assignment.getVariable() instanceof J.Identifier) { - J.Identifier ident = (J.Identifier) assignment.getVariable(); - findVarInScope(ident.getSimpleName()) - .map(var -> methodReferencedVars.computeIfAbsent(method.getMethodType(), k -> new HashSet<>()).add(var)); - } - } - if (parent instanceof MethodCall) { - MethodCall parentMethod = (MethodCall) parent; - int argPos = parentMethod.getArguments().indexOf(boundary.getValue()); - if (argPos == -1) { - return method; - } - String paramName = parentMethod.getMethodType().getParameterNames().get(argPos); - NamedVariable var = acc.getVarTable().getVarByName(parentMethod.getMethodType(), paramName); - if (var != null) { - methodReferencedVars.computeIfAbsent(method.getMethodType(), k -> new HashSet<>()).add(var); - } else { - methodUnresolvedReferencedVars.computeIfAbsent(method.getMethodType(), k -> new HashSet<>()) - .add(new UnresolvedVar(parentMethod.getMethodType(), paramName)); - } - } - return method; - } - - @Override - public J.Return visitReturn(J.Return _return, ExecutionContext ctx) { - if (_return.getExpression() == null) { - return _return; - } - Expression expr = _return.getExpression(); - if (!isJodaExpr(expr)) { - return _return; - } - J methodOrLambda = getCursor().dropParentUntil(j -> j instanceof J.MethodDeclaration || j instanceof J.Lambda).getValue(); - if (methodOrLambda instanceof J.Lambda) { - return _return; - } - J.MethodDeclaration method = (J.MethodDeclaration) methodOrLambda; - Expression updatedExpr = (Expression) new JodaTimeVisitor(acc, true, scopes) - .visit(expr, ctx, getCursor().getParentTreeCursor()); - boolean isSafe = !isJodaExpr(updatedExpr); - - addReferencedVars(expr, method.getMethodType()); - acc.getSafeMethodMap().compute(method.getMethodType(), (k, v) -> v == null ? isSafe : v && isSafe); - if (!isSafe) { - acc.getUnsafeVars().addAll(methodReferencedVars.get(method.getMethodType())); - } - return _return; - } - - private void processMarkersOnExpression(List expressions, NamedVariable var) { - for (Expression expr : expressions) { - Optional mayBeMarker = expr.getMarkers().findFirst(SafeCheckMarker.class); - if (!mayBeMarker.isPresent()) { - continue; - } - SafeCheckMarker marker = mayBeMarker.get(); - if (!marker.isSafe()) { - acc.getUnsafeVars().add(var); - } - if (!marker.getReferences().isEmpty()) { - varDependencies.compute(var, (k, v) -> v == null ? new HashSet<>() : v).addAll(marker.getReferences()); - for (NamedVariable ref : marker.getReferences()) { - varDependencies.compute(ref, (k, v) -> v == null ? new HashSet<>() : v).add(var); - } - } - } - } - - /** - * Traverses the cursor to find the first non-Joda expression in the path. - * If no non-Joda expression is found, it returns the cursor pointing - * to the last Joda expression whose parent is not an Expression. - */ - private static Cursor findBoundaryCursorForJodaExpr(Cursor cursor) { - while (cursor.getValue() instanceof Expression && isJodaExpr(cursor.getValue())) { - Cursor parent = cursor.getParentTreeCursor(); - if (parent.getValue() instanceof J && !(parent.getValue() instanceof Expression)) { - return cursor; - } - cursor = parent; - } - return cursor; - } - - private static boolean isJodaExpr(Expression expression) { - return expression.getType() != null && expression.getType().isAssignableFrom(JODA_CLASS_PATTERN); - } - - private List findSinks(Cursor cursor) { - Option mayBeSinks = Dataflow.startingAt(cursor).findSinks(new JodaTimeFlowSpec()); - if (mayBeSinks.isNone()) { - return emptyList(); - } - return mayBeSinks.some().getExpressionSinks(); - } - - private boolean isClassVar(NamedVariable variable) { - return variable.getVariableType().getOwner() instanceof JavaType.Class; - } - - private void dfs(NamedVariable root, Set visited) { - if (visited.contains(root)) { - return; - } - visited.add(root); - for (NamedVariable dep : varDependencies.getOrDefault(root, emptySet())) { - dfs(dep, visited); - } - } - - private void addReferencedVars(Expression expr, JavaType.Method method) { - Set<@Nullable NamedVariable> referencedVars = new HashSet<>(); - new FindVarReferences().visit(expr, referencedVars, getCursor().getParentTreeCursor()); - referencedVars.remove(null); - methodReferencedVars.computeIfAbsent(method, k -> new HashSet<>()).addAll(referencedVars); - } - - @RequiredArgsConstructor - private class AddSafeCheckMarker extends JavaIsoVisitor { - - @NonNull - private List expressions; - - @Override - public Expression visitExpression(Expression expression, ExecutionContext ctx) { - int index = expressions.indexOf(expression); - if (index == -1) { - return super.visitExpression(expression, ctx); - } - SafeCheckMarker marker = getMarker(expression, ctx); - if (!marker.isSafe()) { - Optional mayBeArgCursor = findArgumentExprCursor(); - if (mayBeArgCursor.isPresent()) { - MethodCall parentMethod = mayBeArgCursor.get().getParentTreeCursor().getValue(); - int argPos = parentMethod.getArguments().indexOf(mayBeArgCursor.get().getValue()); - String paramName = parentMethod.getMethodType().getParameterNames().get(argPos); - unsafeVarsByType.computeIfAbsent(parentMethod.getMethodType(), k -> new HashSet<>()).add(paramName); - } - } - Expression withMarker = expression.withMarkers(expression.getMarkers().addIfAbsent(marker)); - expressions.set(index, withMarker); - return withMarker; - } - - private SafeCheckMarker getMarker(Expression expr, ExecutionContext ctx) { - Optional mayBeMarker = expr.getMarkers().findFirst(SafeCheckMarker.class); - if (mayBeMarker.isPresent()) { - return mayBeMarker.get(); - } - - Cursor boundary = findBoundaryCursorForJodaExpr(getCursor()); - boolean isSafe = true; - if (boundary.getParentTreeCursor().getValue() instanceof J.Return) { - // TODO: handle return statement in lambda - isSafe = boundary.dropParentUntil(j -> j instanceof J.MethodDeclaration || j instanceof J.Lambda) - .getValue() instanceof J.MethodDeclaration; - } - Expression boundaryExpr = boundary.getValue(); - J j = new JodaTimeVisitor(new JodaTimeRecipe.Accumulator(), false, scopes) - .visit(boundaryExpr, ctx, boundary.getParentTreeCursor()); - Set<@Nullable NamedVariable> referencedVars = new HashSet<>(); - new FindVarReferences().visit(expr, referencedVars, getCursor().getParentTreeCursor()); - AtomicBoolean hasJodaType = new AtomicBoolean(); - new HasJodaType().visit(j, hasJodaType); - isSafe = isSafe && !hasJodaType.get() && !referencedVars.contains(null); - referencedVars.remove(null); - return new SafeCheckMarker(UUID.randomUUID(), isSafe, referencedVars); - } - - private Optional findArgumentExprCursor() { - Cursor cursor = getCursor(); - while (cursor.getValue() instanceof Expression && isJodaExpr(cursor.getValue())) { - Cursor parentCursor = cursor.getParentTreeCursor(); - if (parentCursor.getValue() instanceof MethodCall && - ((MethodCall) parentCursor.getValue()).getArguments().contains(cursor.getValue())) { - return Optional.of(cursor); - } - cursor = parentCursor; - } - return Optional.empty(); - } - } - - private class FindVarReferences extends JavaIsoVisitor> { - - @Override - public J.Identifier visitIdentifier(J.Identifier ident, Set<@Nullable NamedVariable> vars) { - if (!isJodaExpr(ident) || ident.getFieldType() == null) { - return ident; - } - if (ident.getFieldType().getOwner() instanceof JavaType.Class) { - vars.add(null); // class variable not supported yet. - } - - // find variable in the closest scope - findVarInScope(ident.getSimpleName()).ifPresent(vars::add); - return ident; - } - } - - private static class HasJodaType extends JavaIsoVisitor { - @Override - public Expression visitExpression(Expression expression, AtomicBoolean hasJodaType) { - if (hasJodaType.get()) { - return expression; - } - if (expression.getType() != null && expression.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { - hasJodaType.set(true); - } - return super.visitExpression(expression, hasJodaType); - } - } - - @Value - private static class UnresolvedVar { - JavaType declaringType; - String varName; - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java b/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java deleted file mode 100644 index f89d45ed4b..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -import lombok.NonNull; -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; -import org.openrewrite.java.migrate.joda.templates.VarTemplates; -import org.openrewrite.java.tree.*; -import org.openrewrite.java.tree.J.VariableDeclarations.NamedVariable; - -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -class JodaTimeVisitor extends ScopeAwareVisitor { - - private final boolean safeMigration; - private final JodaTimeRecipe.Accumulator acc; - - public JodaTimeVisitor(JodaTimeRecipe.Accumulator acc, boolean safeMigration, LinkedList scopes) { - super(scopes); - this.acc = acc; - 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) { - J j = super.visitCompilationUnit(cu, ctx); - if (j != cu) { - maybeRemoveImport(JODA_DATE_TIME); - maybeRemoveImport(JODA_DATE_TIME_ZONE); - maybeRemoveImport(JODA_TIME_FORMAT); - maybeRemoveImport(JODA_DURATION); - maybeRemoveImport(JODA_ABSTRACT_INSTANT); - maybeRemoveImport(JODA_INSTANT); - maybeRemoveImport(JODA_INTERVAL); - maybeRemoveImport("java.util.Locale"); - - maybeAddImport(JAVA_DATE_TIME); - maybeAddImport(JAVA_ZONE_OFFSET); - maybeAddImport(JAVA_ZONE_ID); - maybeAddImport(JAVA_INSTANT); - maybeAddImport(JAVA_TIME_FORMATTER); - maybeAddImport(JAVA_TIME_FORMAT_STYLE); - maybeAddImport(JAVA_DURATION); - maybeAddImport(JAVA_LOCAL_DATE); - maybeAddImport(JAVA_LOCAL_TIME); - maybeAddImport(JAVA_TEMPORAL_ISO_FIELDS); - maybeAddImport(JAVA_CHRONO_FIELD); - maybeAddImport(JAVA_UTIL_DATE); - maybeAddImport(THREE_TEN_EXTRA_INTERVAL); - } - return j; - } - - @Override - public @NonNull J visitMethodDeclaration(@NonNull J.MethodDeclaration method, @NonNull ExecutionContext ctx) { - J.MethodDeclaration m = (J.MethodDeclaration) super.visitMethodDeclaration(method, ctx); - if (m.getReturnTypeExpression() == null || !m.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return m; - } - if (safeMigration && !acc.getSafeMethodMap().getOrDefault(m.getMethodType(), false)) { - return m; - } - - JavaType.Class returnType = TimeClassMap.getJavaTimeType(((JavaType.Class) m.getType()).getFullyQualifiedName()); - J.Identifier returnExpr = TypeTree.build(returnType.getClassName()).withType(returnType).withPrefix(Space.format(" ")); - return m.withReturnTypeExpression(returnExpr) - .withMethodType(m.getMethodType().withReturnType(returnType)); - } - - @Override - public @NonNull J visitVariableDeclarations(@NonNull J.VariableDeclarations multiVariable, @NonNull ExecutionContext ctx) { - 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; - } - 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 - public @NonNull J visitVariable(@NonNull J.VariableDeclarations.NamedVariable variable, @NonNull ExecutionContext ctx) { - if (!variable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return super.visitVariable(variable, ctx); - } - if (acc.getUnsafeVars().contains(variable) || !(variable.getType() instanceof JavaType.Class)) { - return variable; - } - JavaType.Class jodaType = (JavaType.Class) variable.getType(); - return variable - .withType(TimeClassMap.getJavaTimeType(jodaType.getFullyQualifiedName())) - .withInitializer((Expression) visit(variable.getInitializer(), ctx)); - } - - @Override - public @NonNull J visitAssignment(@NonNull J.Assignment assignment, @NonNull ExecutionContext ctx) { - J.Assignment a = (J.Assignment) super.visitAssignment(assignment, ctx); - if (!a.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return a; - } - if (!(a.getVariable() instanceof J.Identifier)) { - return assignment; - } - J.Identifier varName = (J.Identifier) a.getVariable(); - Optional mayBeVar = findVarInScope(varName.getSimpleName()); - if (!mayBeVar.isPresent() || acc.getUnsafeVars().contains(mayBeVar.get())) { - return assignment; - } - return VarTemplates.getTemplate(assignment).map(t -> t.apply( - updateCursor(a), - a.getCoordinates().replace(), - varName, - a.getAssignment())).orElse(assignment); - } - - @Override - public @NonNull J visitNewClass(@NonNull J.NewClass newClass, @NonNull ExecutionContext ctx) { - MethodCall updated = (MethodCall) super.visitNewClass(newClass, ctx); - if (hasJodaType(updated.getArguments())) { - return newClass; - } - return migrateMethodCall(newClass, updated); - } - - - @Override - public @NonNull J visitMethodInvocation(@NonNull J.MethodInvocation method, @NonNull ExecutionContext ctx) { - J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); - - // internal method with Joda class as return type - if (method.getMethodType() != null && - !method.getMethodType().getDeclaringType().isAssignableFrom(JODA_CLASS_PATTERN) && - method.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return migrateNonJodaMethod(method, m); - } - - if (hasJodaType(m.getArguments()) || isJodaVarRef(m.getSelect())) { - return method; - } - return migrateMethodCall(method, m); - } - - @Override - public @NonNull J visitFieldAccess(@NonNull J.FieldAccess fieldAccess, @NonNull ExecutionContext ctx) { - J.FieldAccess f = (J.FieldAccess) super.visitFieldAccess(fieldAccess, ctx); - if (TypeUtils.isOfClassType(f.getType(), JODA_DATE_TIME_ZONE) && "UTC".equals(f.getSimpleName())) { - return JavaTemplate.builder("ZoneOffset.UTC") - .imports(JAVA_ZONE_OFFSET) - .build() - .apply(updateCursor(f), f.getCoordinates().replace()); - } - return f; - } - - @Override - public @NonNull J visitIdentifier(@NonNull J.Identifier ident, @NonNull ExecutionContext ctx) { - if (!isJodaVarRef(ident)) { - return super.visitIdentifier(ident, ctx); - } - if (this.safeMigration) { - Optional mayBeVar = findVarInScope(ident.getSimpleName()); - if (!mayBeVar.isPresent() || acc.getUnsafeVars().contains(mayBeVar.get())) { - return ident; - } - } - - JavaType.FullyQualified jodaType = ((JavaType.Class) ident.getType()); - JavaType.FullyQualified fqType = TimeClassMap.getJavaTimeType(jodaType.getFullyQualifiedName()); - if (fqType == null) { - return ident; - } - return ident.withType(fqType) - .withFieldType(ident.getFieldType().withType(fqType)); - } - - private J migrateMethodCall(MethodCall original, MethodCall updated) { - if (original.getMethodType() == null || !original.getMethodType().getDeclaringType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return updated; // not a joda type, no need to migrate - } - MethodTemplate template = AllTemplates.getTemplate(original); - if (template == null) { - return original; // unhandled case - } - Optional maybeUpdated = applyTemplate(original, updated, template); - if (!maybeUpdated.isPresent()) { - return original; // unhandled case - } - Expression updatedExpr = (Expression) maybeUpdated.get(); - if (!safeMigration || !isArgument(original)) { - return updatedExpr; - } - // this expression is an argument to a method call - MethodCall parentMethod = getCursor().getParentTreeCursor().getValue(); - if (parentMethod.getMethodType().getDeclaringType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return updatedExpr; - } - int argPos = parentMethod.getArguments().indexOf(original); - JavaType paramType = parentMethod.getMethodType().getParameterTypes().get(argPos); - if (TypeUtils.isAssignableTo(paramType, updatedExpr.getType())) { - return updatedExpr; - } - String paramName = parentMethod.getMethodType().getParameterNames().get(argPos); - NamedVariable var = acc.getVarTable().getVarByName(parentMethod.getMethodType(), paramName); - if (var != null && !acc.getUnsafeVars().contains(var)) { - return updatedExpr; - } - return original; - } - - private J.MethodInvocation migrateNonJodaMethod(J.MethodInvocation original, J.MethodInvocation updated) { - if (safeMigration && !acc.getSafeMethodMap().getOrDefault(updated.getMethodType(), false)) { - return original; - } - JavaType.Class returnType = (JavaType.Class) updated.getMethodType().getReturnType(); - JavaType.Class updatedReturnType = TimeClassMap.getJavaTimeType(returnType.getFullyQualifiedName()); - if (updatedReturnType == null) { - return original; // unhandled case - } - return updated.withMethodType(updated.getMethodType().withReturnType(updatedReturnType)) - .withName(updated.getName().withType(updatedReturnType)); - } - - private boolean hasJodaType(List exprs) { - for (Expression expr : exprs) { - JavaType exprType = expr.getType(); - if (exprType != null && exprType.isAssignableFrom(JODA_CLASS_PATTERN)) { - return true; - } - } - return false; - } - - private Optional applyTemplate(MethodCall original, MethodCall updated, MethodTemplate template) { - if (template.getMatcher().matches(original)) { - Expression[] args = template.getTemplateArgsFunc().apply(updated); - if (args.length == 0) { - return Optional.of(template.getTemplate().apply(updateCursor(updated), updated.getCoordinates().replace())); - } - return Optional.of(template.getTemplate().apply(updateCursor(updated), updated.getCoordinates().replace(), (Object[]) args)); - } - return Optional.empty(); // unhandled case - } - - private boolean isJodaVarRef(@Nullable Expression expr) { - if (expr == null || expr.getType() == null || !expr.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return false; - } - if (expr instanceof J.FieldAccess) { - return ((J.FieldAccess) expr).getName().getFieldType() != null; - } - if (expr instanceof J.Identifier) { - return ((J.Identifier) expr).getFieldType() != null; - } - if (expr instanceof MethodCall) { - return expr.getType().isAssignableFrom(JODA_CLASS_PATTERN); - } - return false; - } - - private boolean isArgument(J expr) { - if (!(getCursor().getParentTreeCursor().getValue() instanceof MethodCall)) { - return false; - } - MethodCall methodCall = getCursor().getParentTreeCursor().getValue(); - return methodCall.getArguments().contains(expr); - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/SafeCheckMarker.java b/src/main/java/org/openrewrite/java/migrate/joda/SafeCheckMarker.java deleted file mode 100644 index 7310d4987d..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/SafeCheckMarker.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.With; -import org.openrewrite.java.tree.J.VariableDeclarations.NamedVariable; -import org.openrewrite.marker.Marker; - -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -/** - * A marker to indicate whether an expression is safe to migrate - * and variables that are referenced in the expression. - */ -@Value -@With -public class SafeCheckMarker implements Marker { - @EqualsAndHashCode.Include - UUID id; - boolean isSafe; - Set references; - - public SafeCheckMarker(UUID id, boolean isSafe, Set references) { - this.id = id; - this.isSafe = isSafe; - this.references = references; - } - - public SafeCheckMarker(UUID id, boolean isSafe) { - this(id, isSafe, new HashSet<>()); - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/ScopeAwareVisitor.java b/src/main/java/org/openrewrite/java/migrate/joda/ScopeAwareVisitor.java deleted file mode 100644 index d25157f0e9..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/ScopeAwareVisitor.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -import lombok.AllArgsConstructor; -import lombok.Value; -import org.openrewrite.Cursor; -import org.openrewrite.ExecutionContext; -import org.openrewrite.java.JavaVisitor; -import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.J.VariableDeclarations.NamedVariable; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Optional; -import java.util.Set; - -@AllArgsConstructor -class ScopeAwareVisitor extends JavaVisitor { - protected final LinkedList scopes; - - @Override - public J preVisit(J j, ExecutionContext ctx) { - if (j instanceof J.ClassDeclaration) { - scopes.push(new VariablesInScope(getCursor())); - } - if (j instanceof J.Block) { - scopes.push(new VariablesInScope(getCursor())); - } - if (j instanceof J.MethodDeclaration) { - scopes.push(new VariablesInScope(getCursor())); - } - if (j instanceof J.VariableDeclarations.NamedVariable) { - assert !scopes.isEmpty(); - NamedVariable variable = (NamedVariable) j; - scopes.peek().variables.add(variable); - } - return super.preVisit(j, ctx); - } - - @Override - public J postVisit(J j, ExecutionContext ctx) { - if (j instanceof J.ClassDeclaration) { - scopes.pop(); - } - if (j instanceof J.Block) { - scopes.pop(); - } - if (j instanceof J.MethodDeclaration) { - scopes.pop(); - } - return super.postVisit(j, ctx); - } - - Cursor findScope(NamedVariable variable) { - for (VariablesInScope scope : scopes) { - if (scope.variables.contains(variable)) { - return scope.scope; - } - } - return null; - } - - // Returns the variable in the closest scope - Optional findVarInScope(String varName) { - for (VariablesInScope scope : scopes) { - for (NamedVariable var : scope.variables) { - if (var.getSimpleName().equals(varName)) { - return Optional.of(var); - } - } - } - return Optional.empty(); - } - - Cursor getCurrentScope() { - assert !scopes.isEmpty(); - return scopes.peek().scope; - } - - @Value - public static class VariablesInScope { - Cursor scope; - Set variables; - - public VariablesInScope(Cursor scope) { - this.scope = scope; - this.variables = new HashSet<>(); - } - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/package-info.java b/src/main/java/org/openrewrite/java/migrate/joda/package-info.java deleted file mode 100644 index 0741212ea8..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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. - */ -@NullMarked -@NonNullFields -package org.openrewrite.java.migrate.joda; - -import org.jspecify.annotations.NullMarked; -import org.openrewrite.internal.lang.NonNullFields; diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDateTimeTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDateTimeTemplates.java deleted file mode 100644 index f561541776..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDateTimeTemplates.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_DATE_TIME; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_ABSTRACT_DATE_TIME; - -public class AbstractDateTimeTemplates implements Templates { - private final MethodMatcher getDayOfMonth = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getDayOfMonth()"); - private final MethodMatcher getDayOfWeek = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getDayOfWeek()"); - private final MethodMatcher getHourOfDay = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getHourOfDay()"); - private final MethodMatcher getMillisOfSecond = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getMillisOfSecond()"); - private final MethodMatcher getMinuteOfDay = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getMinuteOfDay()"); - private final MethodMatcher getMinuteOfHour = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getMinuteOfHour()"); - private final MethodMatcher getMonthOfYear = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getMonthOfYear()"); - private final MethodMatcher getSecondOfDay = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getSecondOfDay()"); - private final MethodMatcher getSecondOfMinute = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getSecondOfMinute()"); - private final MethodMatcher getWeekOfWeekyear = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getWeekOfWeekyear()"); - private final MethodMatcher toString = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " toString()"); - - private final JavaTemplate getDayOfMonthTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getDayOfMonth()").build(); - private final JavaTemplate getDayOfWeekTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getDayOfWeek().getValue()").build(); - private final JavaTemplate getHourOfDayTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getHour()").build(); - private final JavaTemplate getMillisOfSecondTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.get(ChronoField.MILLI_OF_SECOND)").imports("java.time.temporal.ChronoField").build(); - private final JavaTemplate getMinuteOfDayTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.get(ChronoField.MINUTE_OF_DAY)").imports("java.time.temporal.ChronoField").build(); - private final JavaTemplate getMinuteOfHourTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getMinute()").build(); - private final JavaTemplate getMonthOfYearTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getMonthValue()").build(); - private final JavaTemplate getSecondOfDayTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.get(ChronoField.SECOND_OF_DAY)").imports("java.time.temporal.ChronoField").build(); - private final JavaTemplate getSecondOfMinuteTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getSecond()").build(); - private final JavaTemplate getWeekOfWeekyearTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.get(ChronoField.ALIGNED_WEEK_OF_YEAR)").imports("java.time.temporal.ChronoField").build(); - private final JavaTemplate toStringTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.toString()").build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(getDayOfMonth, getDayOfMonthTemplate)); - add(new MethodTemplate(getDayOfWeek, getDayOfWeekTemplate)); - add(new MethodTemplate(getHourOfDay, getHourOfDayTemplate)); - add(new MethodTemplate(getMillisOfSecond, getMillisOfSecondTemplate)); - add(new MethodTemplate(getMinuteOfDay, getMinuteOfDayTemplate)); - add(new MethodTemplate(getMinuteOfHour, getMinuteOfHourTemplate)); - add(new MethodTemplate(getMonthOfYear, getMonthOfYearTemplate)); - add(new MethodTemplate(getSecondOfDay, getSecondOfDayTemplate)); - add(new MethodTemplate(getSecondOfMinute, getSecondOfMinuteTemplate)); - add(new MethodTemplate(getWeekOfWeekyear, getWeekOfWeekyearTemplate)); - add(new MethodTemplate(toString, toStringTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDurationTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDurationTemplates.java deleted file mode 100644 index eb1422b678..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDurationTemplates.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_DURATION; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_DURATION; - -public class AbstractDurationTemplates implements Templates { - private final MethodMatcher isLongerThan = new MethodMatcher(JODA_DURATION + " isLongerThan(..)"); - private final MethodMatcher toPeriod = new MethodMatcher(JODA_DURATION + " toPeriod()"); - - private final JavaTemplate isLongerThanTemplate = JavaTemplate.builder("#{any(" + JAVA_DURATION + ")}.compareTo(#{any(" + JAVA_DURATION + ")}) > 0").build(); - private final JavaTemplate toPeriodTemplate = JavaTemplate.builder("#{any(" + JAVA_DURATION + ")}.toPeriod()").build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(isLongerThan, isLongerThanTemplate)); - add(new MethodTemplate(toPeriod, toPeriodTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractInstantTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractInstantTemplates.java deleted file mode 100644 index 77a29c3d71..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractInstantTemplates.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; -import org.openrewrite.java.tree.Expression; -import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.MethodCall; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -public class AbstractInstantTemplates implements Templates { - private final MethodMatcher equals = new MethodMatcher(JODA_ABSTRACT_INSTANT + " equals(java.lang.Object)"); - private final MethodMatcher getZone = new MethodMatcher(JODA_ABSTRACT_INSTANT + " getZone()"); - private final MethodMatcher isAfterLong = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isAfter(long)"); - private final MethodMatcher isAfter = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isAfter(org.joda.time.ReadableInstant)"); - private final MethodMatcher isBeforeLong = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isBefore(long)"); - private final MethodMatcher isBefore = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isBefore(org.joda.time.ReadableInstant)"); - private final MethodMatcher isBeforeNow = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isBeforeNow()"); - private final MethodMatcher isEqualLong = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isEqual(long)"); - private final MethodMatcher isEqualReadableInstant = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isEqual(org.joda.time.ReadableInstant)"); - private final MethodMatcher toDate = new MethodMatcher(JODA_ABSTRACT_INSTANT + " toDate()"); - private final MethodMatcher toInstant = new MethodMatcher(JODA_ABSTRACT_INSTANT + " toInstant()"); - private final MethodMatcher toString = new MethodMatcher(JODA_ABSTRACT_INSTANT + " toString()"); - private final MethodMatcher toStringFormatter = new MethodMatcher(JODA_ABSTRACT_INSTANT + " toString(org.joda.time.format.DateTimeFormatter)"); - - private final JavaTemplate equalsTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.equals(#{any(java.lang.Object)})").build(); - private final JavaTemplate getZoneTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getZone()").build(); - private final JavaTemplate isAfterLongTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.isAfter(Instant.ofEpochMilli(#{any(long)}).atZone(ZoneId.systemDefault()))") - .imports(JAVA_INSTANT, JAVA_ZONE_ID).build(); - private final JavaTemplate isAfterLongTemplateWithInstant = JavaTemplate.builder("#{any(" + JAVA_INSTANT + ")}.isAfter(Instant.ofEpochMilli(#{any(long)}))") - .imports(JAVA_INSTANT).build(); - private final JavaTemplate isAfterTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.isAfter(#{any(" + JAVA_DATE_TIME + ")})").build(); - private final JavaTemplate isAfterTemplateWithInstant = JavaTemplate.builder("#{any(" + JAVA_INSTANT + ")}.isAfter(#{any(" + JAVA_INSTANT + ")})").build(); - private final JavaTemplate isBeforeLongTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.isBefore(Instant.ofEpochMilli(#{any(long)}).atZone(ZoneId.systemDefault()))") - .imports(JAVA_INSTANT, JAVA_ZONE_ID).build(); - private final JavaTemplate isBeforeLongTemplateWithInstant = JavaTemplate.builder("#{any(" + JAVA_INSTANT + ")}.isBefore(Instant.ofEpochMilli(#{any(long)}))") - .imports(JAVA_INSTANT).build(); - private final JavaTemplate isBeforTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.isBefore(#{any(" + JAVA_DATE_TIME + ")})").build(); - private final JavaTemplate isBeforeTemplateWithInstant = JavaTemplate.builder("#{any(" + JAVA_INSTANT + ")}.isBefore(#{any(" + JAVA_INSTANT + ")})").build(); - private final JavaTemplate isBeforeNowTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.isBefore(ZonedDateTime.now())") - .imports(JAVA_DATE_TIME).build(); - private final JavaTemplate isEqualLongTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.isEqual(Instant.ofEpochMilli(#{any(long)}).atZone(ZoneId.systemDefault()))") - .imports(JAVA_INSTANT, JAVA_ZONE_ID).build(); - private final JavaTemplate isEqualReadableInstantTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.isEqual(#{any(" + JAVA_DATE_TIME + ")})").build(); - private final JavaTemplate toDateTemplate = JavaTemplate.builder("Date.from(#{any(" + JAVA_DATE_TIME + ")}.toInstant())") - .imports(JAVA_UTIL_DATE) - .build(); - private final JavaTemplate toInstantTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.toInstant()").build(); - private final JavaTemplate toStringTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.toString()").build(); - private final JavaTemplate toStringFormatterTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.format(#{any(" + JAVA_TIME_FORMATTER + ")})").build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(equals, equalsTemplate)); - add(new MethodTemplate(getZone, getZoneTemplate)); - add(new MethodTemplate(isAfterLong, isAfterLongTemplate)); - add(new MethodTemplate(isAfterLong, isAfterLongTemplateWithInstant)); - add(new MethodTemplate(isAfter, isAfterTemplate)); - add(new MethodTemplate(isAfter, isAfterTemplateWithInstant)); - add(new MethodTemplate(isBeforeLong, isBeforeLongTemplate)); - add(new MethodTemplate(isBeforeLong, isBeforeLongTemplateWithInstant)); - add(new MethodTemplate(isBefore, isBeforTemplate)); - add(new MethodTemplate(isBefore, isBeforeTemplateWithInstant)); - add(new MethodTemplate(isBeforeNow, isBeforeNowTemplate)); - add(new MethodTemplate(isEqualLong, isEqualLongTemplate)); - add(new MethodTemplate(isEqualReadableInstant, isEqualReadableInstantTemplate)); - add(new MethodTemplate(toDate, toDateTemplate)); - add(new MethodTemplate(toInstant, toInstantTemplate)); - add(new MethodTemplate(toString, toStringTemplate)); - add(new MethodTemplate(toStringFormatter, toStringFormatterTemplate)); - } - }; - - @Override - public boolean matchesMethodCall(MethodCall method, MethodTemplate template) { - if (method instanceof J.NewClass) { - return true; - } - Expression select = ((J.MethodInvocation) method).getSelect(); - if (select != null && select.getType() != null && select.getType().isAssignableFrom(Pattern.compile(JODA_INSTANT))) { - return Arrays.asList( - isAfterLongTemplateWithInstant, - isAfterTemplateWithInstant, - isBeforeLongTemplateWithInstant, - isBeforeTemplateWithInstant - ).contains(template.getTemplate()); - } - return true; - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractIntervalTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractIntervalTemplates.java deleted file mode 100644 index 9fe69cdf14..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractIntervalTemplates.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaParser; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -public class AbstractIntervalTemplates implements Templates { - private final MethodMatcher getStart = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " getStart()"); - private final MethodMatcher getEnd = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " getEnd()"); - private final MethodMatcher toDuration = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " toDuration()"); - private final MethodMatcher toDurationMillis = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " toDurationMillis()"); - private final MethodMatcher contains = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " contains(long)"); - - private final JavaTemplate getStartTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.getStart().atZone(ZoneId.systemDefault())") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(JAVA_ZONE_ID) - .build(); - private final JavaTemplate getEndTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.getEnd().atZone(ZoneId.systemDefault())") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(JAVA_ZONE_ID) - .build(); - private final JavaTemplate toDurationTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.toDuration()") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .build(); - private final JavaTemplate toDurationMillisTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.toDuration().toMillis()") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .build(); - private final JavaTemplate containsTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.contains(Instant.ofEpochMilli(#{any(long)}))") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(JAVA_INSTANT) - .build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(getStart, getStartTemplate)); - add(new MethodTemplate(getEnd, getEndTemplate)); - add(new MethodTemplate(toDuration, toDurationTemplate)); - add(new MethodTemplate(toDurationMillis, toDurationMillisTemplate)); - add(new MethodTemplate(contains, containsTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AllTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AllTemplates.java deleted file mode 100644 index 3d79830153..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/AllTemplates.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Value; -import org.openrewrite.java.MethodMatcher; -import org.openrewrite.java.tree.MethodCall; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -public class AllTemplates { - private static final MethodMatcher ANY_BASE_DATETIME = new MethodMatcher(JODA_BASE_DATE_TIME + " *(..)"); - private static final MethodMatcher ANY_NEW_DATE_TIME = new MethodMatcher(JODA_DATE_TIME + "(..)"); - private static final MethodMatcher ANY_DATE_TIME = new MethodMatcher(JODA_DATE_TIME + " *(..)"); - private static final MethodMatcher ANY_DATE_TIMEZONE = new MethodMatcher(JODA_DATE_TIME_ZONE + " *(..)"); - private static final MethodMatcher ANY_TIME_FORMAT = new MethodMatcher(JODA_TIME_FORMAT + " *(..)"); - private static final MethodMatcher ANY_TIME_FORMATTER = new MethodMatcher(JODA_TIME_FORMATTER + " *(..)"); - private static final MethodMatcher ANY_NEW_DURATION = new MethodMatcher(JODA_DURATION + "(..)"); - private static final MethodMatcher ANY_DURATION = new MethodMatcher(JODA_DURATION + " *(..)"); - private static final MethodMatcher ANY_BASE_DURATION = new MethodMatcher(JODA_BASE_DURATION + " *(..)"); - private static final MethodMatcher ANY_ABSTRACT_INSTANT = new MethodMatcher(JODA_ABSTRACT_INSTANT + " *(..)"); - private static final MethodMatcher ANY_ABSTRACT_DATE_TIME = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " *(..)"); - private static final MethodMatcher ANY_ABSTRACT_DURATION = new MethodMatcher(JODA_ABSTRACT_DURATION + " *(..)"); - private static final MethodMatcher ANY_INSTANT = new MethodMatcher(JODA_INSTANT + " *(..)"); - private static final MethodMatcher ANY_NEW_INSTANT = new MethodMatcher(JODA_INSTANT + "(..)"); - private static final MethodMatcher ANY_NEW_INTERVAL = new MethodMatcher(JODA_INTERVAL + "(..)"); - private static final MethodMatcher ANY_ABSTRACT_INTERVAL = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " *(..)"); - private static final MethodMatcher ANY_BASE_INTERVAL = new MethodMatcher(JODA_BASE_INTERVAL + " *(..)"); - - private static List templates = new ArrayList() { - { - add(new MatcherAndTemplates(ANY_ABSTRACT_DATE_TIME, new AbstractDateTimeTemplates())); - add(new MatcherAndTemplates(ANY_ABSTRACT_DURATION, new AbstractDurationTemplates())); - add(new MatcherAndTemplates(ANY_ABSTRACT_INSTANT, new AbstractInstantTemplates())); - add(new MatcherAndTemplates(ANY_BASE_DATETIME, new BaseDateTime())); - add(new MatcherAndTemplates(ANY_TIME_FORMAT, new DateTimeFormatTemplates())); - add(new MatcherAndTemplates(ANY_TIME_FORMATTER, new DateTimeFormatterTemplates())); - add(new MatcherAndTemplates(ANY_NEW_DATE_TIME, new DateTimeTemplates())); - add(new MatcherAndTemplates(ANY_DATE_TIME, new DateTimeTemplates())); - add(new MatcherAndTemplates(ANY_NEW_DURATION, new DurationTemplates())); - add(new MatcherAndTemplates(ANY_DURATION, new DurationTemplates())); - add(new MatcherAndTemplates(ANY_BASE_DURATION, new BaseDurationTemplates())); - add(new MatcherAndTemplates(ANY_DATE_TIMEZONE, new TimeZoneTemplates())); - add(new MatcherAndTemplates(ANY_INSTANT, new InstantTemplates())); - add(new MatcherAndTemplates(ANY_NEW_INSTANT, new InstantTemplates())); - add(new MatcherAndTemplates(ANY_NEW_INTERVAL, new IntervalTemplates())); - add(new MatcherAndTemplates(ANY_ABSTRACT_INTERVAL, new AbstractIntervalTemplates())); - add(new MatcherAndTemplates(ANY_BASE_INTERVAL, new BaseIntervalTemplates())); - } - }; - - public static MethodTemplate getTemplate(MethodCall method) { - return getTemplateGroup(method).flatMap(templates -> templates.getTemplates().stream() - .filter(template -> template.getMatcher().matches(method) && templates.matchesMethodCall(method, template)) - .findFirst()).orElse(null); - } - - private static Optional getTemplateGroup(MethodCall method) { - for (MatcherAndTemplates matcherAndTemplates : templates) { - if (matcherAndTemplates.getMatcher().matches(method)) { - return Optional.of(matcherAndTemplates.getTemplates()); - } - } - return Optional.empty(); - } - - @Value - private static class MatcherAndTemplates { - MethodMatcher matcher; - Templates templates; - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseDateTime.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseDateTime.java deleted file mode 100644 index 1e1dc299b6..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseDateTime.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_BASE_DATE_TIME; - -public class BaseDateTime implements Templates { - private final MethodMatcher getMillis = new MethodMatcher(JODA_BASE_DATE_TIME + " getMillis()"); - - private final JavaTemplate getMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toInstant().toEpochMilli()") - .build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(getMillis, getMillisTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseDurationTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseDurationTemplates.java deleted file mode 100644 index aa23fa6385..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseDurationTemplates.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_DURATION; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_BASE_DURATION; - -public class BaseDurationTemplates implements Templates { - private final MethodMatcher getMillis = new MethodMatcher(JODA_BASE_DURATION + " getMillis()"); - - private final JavaTemplate getMillisTemplate = JavaTemplate.builder("#{any(" + JAVA_DURATION + ")}.toMillis()").build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(getMillis, getMillisTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseIntervalTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseIntervalTemplates.java deleted file mode 100644 index afe6a70e35..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseIntervalTemplates.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaParser; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_BASE_INTERVAL; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.THREE_TEN_EXTRA_INTERVAL; - -public class BaseIntervalTemplates implements Templates { - private final MethodMatcher getStartMillis = new MethodMatcher(JODA_BASE_INTERVAL + " getStartMillis()"); - private final MethodMatcher getEndMillis = new MethodMatcher(JODA_BASE_INTERVAL + " getEndMillis()"); - - private final JavaTemplate getStartMillisTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.getStart().toEpochMilli()") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .build(); - private final JavaTemplate getEndMillisTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.getEnd().toEpochMilli()") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(getStartMillis, getStartMillisTemplate)); - add(new MethodTemplate(getEndMillis, getEndMillisTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeFormatTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeFormatTemplates.java deleted file mode 100644 index 0389d50ed3..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeFormatTemplates.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -public class DateTimeFormatTemplates implements Templates { - private final MethodMatcher forPattern = new MethodMatcher(JODA_TIME_FORMAT + " forPattern(String)"); - private final MethodMatcher shortDate = new MethodMatcher(JODA_TIME_FORMAT + " shortDate()"); - private final MethodMatcher mediumDate = new MethodMatcher(JODA_TIME_FORMAT + " mediumDate()"); - private final MethodMatcher longDate = new MethodMatcher(JODA_TIME_FORMAT + " longDate()"); - private final MethodMatcher fullDate = new MethodMatcher(JODA_TIME_FORMAT + " fullDate()"); - private final MethodMatcher shortTime = new MethodMatcher(JODA_TIME_FORMAT + " shortTime()"); - private final MethodMatcher mediumTime = new MethodMatcher(JODA_TIME_FORMAT + " mediumTime()"); - private final MethodMatcher longTime = new MethodMatcher(JODA_TIME_FORMAT + " longTime()"); - private final MethodMatcher fullTime = new MethodMatcher(JODA_TIME_FORMAT + " fullTime()"); - private final MethodMatcher shortDateTime = new MethodMatcher(JODA_TIME_FORMAT + " shortDateTime()"); - private final MethodMatcher mediumDateTime = new MethodMatcher(JODA_TIME_FORMAT + " mediumDateTime()"); - private final MethodMatcher longDateTime = new MethodMatcher(JODA_TIME_FORMAT + " longDateTime()"); - private final MethodMatcher fullDateTime = new MethodMatcher(JODA_TIME_FORMAT + " fullDateTime()"); - - private final JavaTemplate ofPatternTemplate = JavaTemplate.builder("DateTimeFormatter.ofPattern(#{any(String)})") - .imports("java.time.format.DateTimeFormatter") - .build(); - private final JavaTemplate shortDateTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate mediumDateTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate longDateTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate fullDateTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate shortTimeTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate mediumTimeTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate longTimeTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedTime(FormatStyle.LONG)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate fullTimeTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate shortDateTimeTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate mediumDateTimeTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.MEDIUM)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate longDateTimeTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.LONG)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - private final JavaTemplate fullDateTimeTemplate = JavaTemplate.builder("DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL)") - .imports(JAVA_TIME_FORMATTER, JAVA_TIME_FORMAT_STYLE) - .build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(forPattern, ofPatternTemplate)); - add(new MethodTemplate(shortDate, shortDateTemplate)); - add(new MethodTemplate(mediumDate, mediumDateTemplate)); - add(new MethodTemplate(longDate, longDateTemplate)); - add(new MethodTemplate(fullDate, fullDateTemplate)); - add(new MethodTemplate(shortTime, shortTimeTemplate)); - add(new MethodTemplate(mediumTime, mediumTimeTemplate)); - add(new MethodTemplate(longTime, longTimeTemplate)); - add(new MethodTemplate(fullTime, fullTimeTemplate)); - add(new MethodTemplate(shortDateTime, shortDateTimeTemplate)); - add(new MethodTemplate(mediumDateTime, mediumDateTimeTemplate)); - add(new MethodTemplate(longDateTime, longDateTimeTemplate)); - add(new MethodTemplate(fullDateTime, fullDateTimeTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeFormatterTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeFormatterTemplates.java deleted file mode 100644 index 711ec20166..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeFormatterTemplates.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; -import org.openrewrite.java.tree.Expression; -import org.openrewrite.java.tree.J; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -public class DateTimeFormatterTemplates implements Templates { - private final MethodMatcher parseDateTime = new MethodMatcher(JODA_TIME_FORMATTER + " parseDateTime(java.lang.String)"); - private final MethodMatcher parseMillis = new MethodMatcher(JODA_TIME_FORMATTER + " parseMillis(java.lang.String)"); - private final MethodMatcher printLong = new MethodMatcher(JODA_TIME_FORMATTER + " print(long)"); - private final MethodMatcher printDateTime = new MethodMatcher(JODA_TIME_FORMATTER + " print(org.joda.time.ReadableInstant)"); - private final MethodMatcher withZone = new MethodMatcher(JODA_TIME_FORMATTER + " withZone(org.joda.time.DateTimeZone)"); - private final MethodMatcher withZoneUTC = new MethodMatcher(JODA_TIME_FORMATTER + " withZoneUTC()"); - - private final JavaTemplate parseDateTimeTemplate = JavaTemplate.builder("ZonedDateTime.parse(#{any(java.lang.String)}, #{any(" + JAVA_TIME_FORMATTER + ")})") - .imports(JAVA_DATE_TIME).build(); - private final JavaTemplate parseMillisTemplate = JavaTemplate.builder("ZonedDateTime.parse(#{any(java.lang.String)}, #{any(" + JAVA_TIME_FORMATTER + ")}).toInstant().toEpochMilli()") - .imports(JAVA_DATE_TIME).build(); - private final JavaTemplate printLongTemplate = JavaTemplate.builder("ZonedDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}), ZoneId.systemDefault()).format( #{any(" + JAVA_TIME_FORMATTER + ")})") - .imports(JAVA_DATE_TIME, JAVA_INSTANT, JAVA_ZONE_ID) - .build(); - private final JavaTemplate printDateTimeTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.format(#{any(" + JAVA_TIME_FORMATTER + ")})").build(); - private final JavaTemplate withZoneTemplate = JavaTemplate.builder("#{any(" + JAVA_TIME_FORMATTER + ")}.withZone(#{any(" + JAVA_ZONE_ID + ")})").build(); - private final JavaTemplate withZoneUTCTemplate = JavaTemplate.builder("#{any(" + JAVA_TIME_FORMATTER + ")}.withZone(ZoneOffset.UTC)") - .imports(JAVA_ZONE_OFFSET).build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(parseDateTime, parseDateTimeTemplate, m -> { - J.MethodInvocation mi = (J.MethodInvocation) m; - return new Expression[]{mi.getArguments().get(0), mi.getSelect()}; - })); - add(new MethodTemplate(parseMillis, parseMillisTemplate, m -> { - J.MethodInvocation mi = (J.MethodInvocation) m; - return new Expression[]{mi.getArguments().get(0), mi.getSelect()}; - })); - add(new MethodTemplate(printLong, printLongTemplate, m -> { - J.MethodInvocation mi = (J.MethodInvocation) m; - return new Expression[]{mi.getArguments().get(0), mi.getSelect()}; - })); - add(new MethodTemplate(printDateTime, printDateTimeTemplate, m -> { - J.MethodInvocation mi = (J.MethodInvocation) m; - return new Expression[]{mi.getArguments().get(0), mi.getSelect()}; - })); - add(new MethodTemplate(withZone, withZoneTemplate)); - add(new MethodTemplate(withZoneUTC, withZoneUTCTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeTemplates.java deleted file mode 100644 index 85ea7b451f..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeTemplates.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; -import org.openrewrite.java.tree.Expression; -import org.openrewrite.java.tree.J; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -@NoArgsConstructor -public class DateTimeTemplates implements Templates { - private final MethodMatcher newDateTime = new MethodMatcher(JODA_DATE_TIME + "()"); - private final MethodMatcher newDateTimeWithZone = new MethodMatcher(JODA_DATE_TIME + "(" + JODA_DATE_TIME_ZONE + ")"); - private final MethodMatcher newDateTimeWithEpoch = new MethodMatcher(JODA_DATE_TIME + "(long)"); - private final MethodMatcher newDateTimeWithEpochAndZone = new MethodMatcher(JODA_DATE_TIME + "(long, " + JODA_DATE_TIME_ZONE + ")"); - private final MethodMatcher newDateTimeWithMin = new MethodMatcher(JODA_DATE_TIME + "(int, int, int, int, int)"); - private final MethodMatcher newDateTimeWithMinAndZone = new MethodMatcher(JODA_DATE_TIME + "(int, int, int, int, int, " + JODA_DATE_TIME_ZONE + ")"); - private final MethodMatcher newDateTimeWithSec = new MethodMatcher(JODA_DATE_TIME + "(int, int, int, int, int, int)"); - private final MethodMatcher newDateTimeWithSecAndZone = new MethodMatcher(JODA_DATE_TIME + "(int, int, int, int, int, int, " + JODA_DATE_TIME_ZONE + ")"); - private final MethodMatcher newDateTimeWithMillis = new MethodMatcher(JODA_DATE_TIME + "(int, int, int, int, int, int, int)"); - private final MethodMatcher newDateTimeWithMillisAndZone = new MethodMatcher(JODA_DATE_TIME + "(int, int, int, int, int, int, int, " + JODA_DATE_TIME_ZONE + ")"); - - private final MethodMatcher dateTimeNow = new MethodMatcher(JODA_DATE_TIME + " now()"); - private final MethodMatcher dateTimeNowWithZone = new MethodMatcher(JODA_DATE_TIME + " now(" + JODA_DATE_TIME_ZONE + ")"); - private final MethodMatcher dateTimeParse = new MethodMatcher(JODA_DATE_TIME + " parse(String)"); - private final MethodMatcher dateTimeParseWithFormatter = new MethodMatcher(JODA_DATE_TIME + " parse(String, " + JODA_TIME_FORMATTER + ")"); - - private final MethodMatcher toDateTime = new MethodMatcher(JODA_DATE_TIME + " toDateTime()"); - private final MethodMatcher toDateTimeWithZone = new MethodMatcher(JODA_DATE_TIME + " toDateTime(" + JODA_DATE_TIME_ZONE + ")"); - private final MethodMatcher withMillis = new MethodMatcher(JODA_DATE_TIME + " withMillis(long)"); - private final MethodMatcher withZone = new MethodMatcher(JODA_DATE_TIME + " withZone(" + JODA_DATE_TIME_ZONE + ")"); - private final MethodMatcher withZoneRetainFields = new MethodMatcher(JODA_DATE_TIME + " withZoneRetainFields(" + JODA_DATE_TIME_ZONE + ")"); - private final MethodMatcher withEarlierOffsetAtOverlap = new MethodMatcher(JODA_DATE_TIME + " withEarlierOffsetAtOverlap()"); - private final MethodMatcher withLaterOffsetAtOverlap = new MethodMatcher(JODA_DATE_TIME + " withLaterOffsetAtOverlap()"); - private final MethodMatcher withDate = new MethodMatcher(JODA_DATE_TIME + " withDate(int, int, int)"); - private final MethodMatcher withDateLocalDate = new MethodMatcher(JODA_DATE_TIME + " withDate(" + JODA_LOCAL_DATE + ")"); - private final MethodMatcher withTime = new MethodMatcher(JODA_DATE_TIME + " withTime(int, int, int, int)"); - private final MethodMatcher withTimeLocalTime = new MethodMatcher(JODA_DATE_TIME + " withTime(" + JODA_LOCAL_TIME + ")"); - private final MethodMatcher withTimeAtStartOfDay = new MethodMatcher(JODA_DATE_TIME + " withTimeAtStartOfDay()"); - private final MethodMatcher withField = new MethodMatcher(JODA_DATE_TIME + " withField(" + JODA_DATE_TIME_FIELD_TYPE + ", int)"); - private final MethodMatcher withFieldAdded = new MethodMatcher(JODA_DATE_TIME + " withFieldAdded(" + JODA_DURATION_FIELD_TYPE + ", int)"); - private final MethodMatcher withDurationAdded = new MethodMatcher(JODA_DATE_TIME + " withDurationAdded(long, int)"); - private final MethodMatcher plusLong = new MethodMatcher(JODA_DATE_TIME + " plus(long)"); - private final MethodMatcher plusReadableDuration = new MethodMatcher(JODA_DATE_TIME + " plus(" + JODA_READABLE_DURATION + ")"); - private final MethodMatcher plusYears = new MethodMatcher(JODA_DATE_TIME + " plusYears(int)"); - private final MethodMatcher plusMonths = new MethodMatcher(JODA_DATE_TIME + " plusMonths(int)"); - private final MethodMatcher plusWeeks = new MethodMatcher(JODA_DATE_TIME + " plusWeeks(int)"); - private final MethodMatcher plusDays = new MethodMatcher(JODA_DATE_TIME + " plusDays(int)"); - private final MethodMatcher plusHours = new MethodMatcher(JODA_DATE_TIME + " plusHours(int)"); - private final MethodMatcher plusMinutes = new MethodMatcher(JODA_DATE_TIME + " plusMinutes(int)"); - private final MethodMatcher plusSeconds = new MethodMatcher(JODA_DATE_TIME + " plusSeconds(int)"); - private final MethodMatcher plusMillis = new MethodMatcher(JODA_DATE_TIME + " plusMillis(int)"); - private final MethodMatcher minusLong = new MethodMatcher(JODA_DATE_TIME + " minus(long)"); - private final MethodMatcher minusReadableDuration = new MethodMatcher(JODA_DATE_TIME + " minus(" + JODA_READABLE_DURATION + ")"); - private final MethodMatcher minusYears = new MethodMatcher(JODA_DATE_TIME + " minusYears(int)"); - private final MethodMatcher minusMonths = new MethodMatcher(JODA_DATE_TIME + " minusMonths(int)"); - private final MethodMatcher minusWeeks = new MethodMatcher(JODA_DATE_TIME + " minusWeeks(int)"); - private final MethodMatcher minusDays = new MethodMatcher(JODA_DATE_TIME + " minusDays(int)"); - private final MethodMatcher minusHours = new MethodMatcher(JODA_DATE_TIME + " minusHours(int)"); - private final MethodMatcher minusMinutes = new MethodMatcher(JODA_DATE_TIME + " minusMinutes(int)"); - private final MethodMatcher minusSeconds = new MethodMatcher(JODA_DATE_TIME + " minusSeconds(int)"); - private final MethodMatcher minusMillis = new MethodMatcher(JODA_DATE_TIME + " minusMillis(int)"); - private final MethodMatcher toDateMidnight = new MethodMatcher(JODA_DATE_TIME + " toDateMidnight()"); - private final MethodMatcher toYearMonthDay = new MethodMatcher(JODA_DATE_TIME + " toYearMonthDay()"); - private final MethodMatcher toTimeOfDay = new MethodMatcher(JODA_DATE_TIME + " toTimeOfDay()"); - private final MethodMatcher toLocalDateTime = new MethodMatcher(JODA_DATE_TIME + " toLocalDateTime()"); - private final MethodMatcher toLocalDate = new MethodMatcher(JODA_DATE_TIME + " toLocalDate()"); - private final MethodMatcher toLocalTime = new MethodMatcher(JODA_DATE_TIME + " toLocalTime()"); - private final MethodMatcher withEra = new MethodMatcher(JODA_DATE_TIME + " withEra(int)"); - private final MethodMatcher withCenturyOfEra = new MethodMatcher(JODA_DATE_TIME + " withCenturyOfEra(int)"); - private final MethodMatcher withYearOfEra = new MethodMatcher(JODA_DATE_TIME + " withYearOfEra(int)"); - private final MethodMatcher withYearOfCentury = new MethodMatcher(JODA_DATE_TIME + " withYearOfCentury(int)"); - private final MethodMatcher withYear = new MethodMatcher(JODA_DATE_TIME + " withYear(int)"); - private final MethodMatcher withWeekyear = new MethodMatcher(JODA_DATE_TIME + " withWeekyear(int)"); - private final MethodMatcher withMonthOfYear = new MethodMatcher(JODA_DATE_TIME + " withMonthOfYear(int)"); - private final MethodMatcher withWeekOfWeekyear = new MethodMatcher(JODA_DATE_TIME + " withWeekOfWeekyear(int)"); - private final MethodMatcher withDayOfYear = new MethodMatcher(JODA_DATE_TIME + " withDayOfYear(int)"); - private final MethodMatcher withDayOfMonth = new MethodMatcher(JODA_DATE_TIME + " withDayOfMonth(int)"); - private final MethodMatcher withDayOfWeek = new MethodMatcher(JODA_DATE_TIME + " withDayOfWeek(int)"); - private final MethodMatcher withHourOfDay = new MethodMatcher(JODA_DATE_TIME + " withHourOfDay(int)"); - private final MethodMatcher withMinuteOfHour = new MethodMatcher(JODA_DATE_TIME + " withMinuteOfHour(int)"); - private final MethodMatcher withSecondOfMinute = new MethodMatcher(JODA_DATE_TIME + " withSecondOfMinute(int)"); - private final MethodMatcher withMillisOfSecond = new MethodMatcher(JODA_DATE_TIME + " withMillisOfSecond(int)"); - private final MethodMatcher withMillisOfDay = new MethodMatcher(JODA_DATE_TIME + " withMillisOfDay(int)"); - private final MethodMatcher era = new MethodMatcher(JODA_DATE_TIME + " era()"); - private final MethodMatcher centuryOfEra = new MethodMatcher(JODA_DATE_TIME + " centuryOfEra()"); - private final MethodMatcher yearOfCentury = new MethodMatcher(JODA_DATE_TIME + " yearOfCentury()"); - private final MethodMatcher yearOfEra = new MethodMatcher(JODA_DATE_TIME + " yearOfEra()"); - private final MethodMatcher year = new MethodMatcher(JODA_DATE_TIME + " year()"); - private final MethodMatcher weekyear = new MethodMatcher(JODA_DATE_TIME + " weekyear()"); - private final MethodMatcher monthOfYear = new MethodMatcher(JODA_DATE_TIME + " monthOfYear()"); - private final MethodMatcher weekOfWeekyear = new MethodMatcher(JODA_DATE_TIME + " weekOfWeekyear()"); - private final MethodMatcher dayOfYear = new MethodMatcher(JODA_DATE_TIME + " dayOfYear()"); - private final MethodMatcher dayOfMonth = new MethodMatcher(JODA_DATE_TIME + " dayOfMonth()"); - private final MethodMatcher dayOfWeek = new MethodMatcher(JODA_DATE_TIME + " dayOfWeek()"); - private final MethodMatcher hourOfDay = new MethodMatcher(JODA_DATE_TIME + " hourOfDay()"); - private final MethodMatcher minuteOfDay = new MethodMatcher(JODA_DATE_TIME + " minuteOfDay()"); - private final MethodMatcher minuteOfHour = new MethodMatcher(JODA_DATE_TIME + " minuteOfHour()"); - private final MethodMatcher secondOfDay = new MethodMatcher(JODA_DATE_TIME + " secondOfDay()"); - private final MethodMatcher secondOfMinute = new MethodMatcher(JODA_DATE_TIME + " secondOfMinute()"); - private final MethodMatcher millisOfDay = new MethodMatcher(JODA_DATE_TIME + " millisOfDay()"); - private final MethodMatcher millisOfSecond = new MethodMatcher(JODA_DATE_TIME + " millisOfSecond()"); - - - private final JavaTemplate dateTimeTemplate = JavaTemplate.builder("ZonedDateTime.now()") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate dateTimeWithZoneTemplate = JavaTemplate.builder("ZonedDateTime.now(#{any(java.time.ZoneOffset)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate dateTimeWithEpochTemplate = JavaTemplate.builder("ZonedDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}), ZoneId.systemDefault())") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID, JAVA_INSTANT) - .build(); - private final JavaTemplate dateTimeWithEpochAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}), #{any(java.time.ZoneId)})") - .imports(JAVA_DATE_TIME, JAVA_ZONE_OFFSET, JAVA_ZONE_ID, JAVA_INSTANT) - .build(); - private final JavaTemplate dateTimeWithMinTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, 0, ZoneId.systemDefault())") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID) - .build(); - private final JavaTemplate dateTimeWithMinAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, 0, #{any(java.time.ZoneId)})") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID) - .build(); - private final JavaTemplate dateTimeWithSecTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, ZoneId.systemDefault())") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID) - .build(); - private final JavaTemplate dateTimeWithSecAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, #{any(java.time.ZoneId)})") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID) - .build(); - private final JavaTemplate dateTimeWithMillisTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)} * 1_000_000, ZoneId.systemDefault())") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID) - .build(); - private final JavaTemplate dateTimeWithMillisAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)} * 1_000_000, #{any(java.time.ZoneId)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate dateTimeParseTemplate = JavaTemplate.builder("ZonedDateTime.parse(#{any(String)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate dateTimeParseWithFormatterTemplate = JavaTemplate.builder("ZonedDateTime.parse(#{any(String)}, #{any(java.time.format.DateTimeFormatter)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate toDateTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}") - .build(); - private final JavaTemplate getMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toInstant().toEpochMilli()") - .build(); - private final JavaTemplate withMillisTemplate = JavaTemplate.builder("ZonedDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}),#{any(java.time.ZonedDateTime)}.getZone())") - .imports(JAVA_DATE_TIME, JAVA_INSTANT) - .build(); - private final JavaTemplate withZoneTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withZoneSameInstant(#{any(java.time.ZoneId)})") - .build(); - private final JavaTemplate withZoneRetainFieldsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withZoneSameLocal(#{any(java.time.ZoneId)})") - .build(); - private final JavaTemplate withEarlierOffsetAtOverlapTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withEarlierOffsetAtOverlap()") - .build(); - private final JavaTemplate withLaterOffsetAtOverlapTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withLaterOffsetAtOverlap()") - .build(); - private final JavaTemplate withDateTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withYear(#{any(int)}).withMonth(#{any(int)}).withDayOfMonth(#{any(int)})") - .build(); - private final JavaTemplate withTemporalAdjusterTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(#{any(java.time.temporal.TemporalAdjuster)})") - .imports(JAVA_TEMPORAL_ADJUSTER) - .build(); - private final JavaTemplate withTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withHour(#{any(int)}).withMinute(#{any(int)}).withSecond(#{any(int)}).withNano(#{any(int)} * 1_000_000)") - .build(); - private final JavaTemplate withTimeAtStartOfDayTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalDate().atStartOfDay(#{any(java.time.ZonedDateTime)}.getZone())") - .build(); - private final JavaTemplate withDurationAddedTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plus(Duration.ofMillis(#{any(long)}).multipliedBy(#{any(int)}))") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate plusReadableDurationTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plus(#{any(java.time.Duration)})") - .build(); - private final JavaTemplate plusYearsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusYears(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate plusMonthsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusMonths(#{any(int)})") - .build(); - private final JavaTemplate plusWeeksTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusWeeks(#{any(int)})") - .build(); - private final JavaTemplate plusDaysTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusDays(#{any(int)})") - .build(); - private final JavaTemplate plusHoursTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusHours(#{any(int)})") - .build(); - private final JavaTemplate plusMinutesTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusMinutes(#{any(int)})") - .build(); - private final JavaTemplate plusSecondsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusSeconds(#{any(int)})") - .build(); - private final JavaTemplate plusMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plus(Duration.ofMillis(#{any(int)}))") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate minusMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minus(Duration.ofMillis(#{any(int)}))") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate minusReadableDurationTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minus(#{any(java.time.Duration)})") - .imports(JAVA_DATE_TIME, JAVA_DURATION) - .build(); - private final JavaTemplate minusYearsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusYears(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusMonthsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusMonths(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusWeeksTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusWeeks(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusDaysTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusDays(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusHoursTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusHours(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusMinutesTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusMinutes(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusSecondsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusSeconds(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate toLocalDateTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalDateTime()") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate toLocalDateTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalDate()") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate toLocalTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalTime()") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate withYearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withYear(#{any(int)})") - .build(); - private final JavaTemplate withWeekyearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(IsoFields.WEEK_BASED_YEAR, #{any(int)})") - .imports(JAVA_TEMPORAL_ISO_FIELDS) - .build(); - private final JavaTemplate withMonthOfYearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withMonth(#{any(int)})") - .build(); - private final JavaTemplate withWeekOfWeekyearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(ChronoField.ALIGNED_WEEK_OF_YEAR, #{any(int)})") - .imports(JAVA_CHRONO_FIELD) - .build(); - private final JavaTemplate withDayOfYearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withDayOfYear(#{any(int)})") - .build(); - private final JavaTemplate withDayOfMonthTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withDayOfMonth(#{any(int)})") - .build(); - private final JavaTemplate withDayOfWeekTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(ChronoField.DAY_OF_WEEK, #{any(int)})") - .imports(JAVA_CHRONO_FIELD) - .build(); - private final JavaTemplate withHourOfDayTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withHour(#{any(int)})") - .build(); - private final JavaTemplate withMinuteOfHourTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withMinute(#{any(int)})") - .build(); - private final JavaTemplate withSecondOfMinuteTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withSecond(#{any(int)})") - .build(); - private final JavaTemplate withMillisOfSecondTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withNano(#{any(int)} * 1_000_000)") - .build(); - private final JavaTemplate withMillisOfDayTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(ChronoField.MILLI_OF_DAY, #{any(int)})") - .imports(JAVA_CHRONO_FIELD) - .build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(newDateTime, dateTimeTemplate)); - add(new MethodTemplate(newDateTimeWithZone, dateTimeWithZoneTemplate)); - add(new MethodTemplate(newDateTimeWithEpoch, dateTimeWithEpochTemplate)); - add(new MethodTemplate(newDateTimeWithEpochAndZone, dateTimeWithEpochAndZoneTemplate)); - add(new MethodTemplate(newDateTimeWithMin, dateTimeWithMinTemplate)); - add(new MethodTemplate(newDateTimeWithMinAndZone, dateTimeWithMinAndZoneTemplate)); - add(new MethodTemplate(newDateTimeWithSec, dateTimeWithSecTemplate)); - add(new MethodTemplate(newDateTimeWithSecAndZone, dateTimeWithSecAndZoneTemplate)); - add(new MethodTemplate(newDateTimeWithMillis, dateTimeWithMillisTemplate)); - add(new MethodTemplate(newDateTimeWithMillisAndZone, dateTimeWithMillisAndZoneTemplate)); - add(new MethodTemplate(dateTimeNow, dateTimeTemplate)); - add(new MethodTemplate(dateTimeNowWithZone, dateTimeWithZoneTemplate)); - add(new MethodTemplate(dateTimeParse, dateTimeParseTemplate)); - add(new MethodTemplate(dateTimeParseWithFormatter, dateTimeParseWithFormatterTemplate)); - add(new MethodTemplate(toDateTime, toDateTimeTemplate)); - add(new MethodTemplate(toDateTimeWithZone, withZoneTemplate)); - add(new MethodTemplate(withMillis, withMillisTemplate, m -> { - J.MethodInvocation mi = (J.MethodInvocation) m; - return new Expression[]{mi.getArguments().get(0), mi.getSelect()}; - })); - add(new MethodTemplate(withZone, withZoneTemplate)); - add(new MethodTemplate(withZoneRetainFields, withZoneRetainFieldsTemplate)); - add(new MethodTemplate(withEarlierOffsetAtOverlap, withEarlierOffsetAtOverlapTemplate)); - add(new MethodTemplate(withLaterOffsetAtOverlap, withLaterOffsetAtOverlapTemplate)); - add(new MethodTemplate(withDate, withDateTemplate)); - add(new MethodTemplate(withDateLocalDate, withTemporalAdjusterTemplate)); - add(new MethodTemplate(withTime, withTimeTemplate)); - add(new MethodTemplate(withTimeLocalTime, withTemporalAdjusterTemplate)); - add(new MethodTemplate(withTimeAtStartOfDay, withTimeAtStartOfDayTemplate, m -> { - J.MethodInvocation mi = (J.MethodInvocation) m; - return new Expression[]{mi.getSelect(), mi.getSelect()}; - })); - add(new MethodTemplate(withDurationAdded, withDurationAddedTemplate)); - add(new MethodTemplate(plusLong, plusMillisTemplate)); - add(new MethodTemplate(plusReadableDuration, plusReadableDurationTemplate)); - add(new MethodTemplate(plusYears, plusYearsTemplate)); - add(new MethodTemplate(plusMonths, plusMonthsTemplate)); - add(new MethodTemplate(plusWeeks, plusWeeksTemplate)); - add(new MethodTemplate(plusDays, plusDaysTemplate)); - add(new MethodTemplate(plusHours, plusHoursTemplate)); - add(new MethodTemplate(plusMinutes, plusMinutesTemplate)); - add(new MethodTemplate(plusSeconds, plusSecondsTemplate)); - add(new MethodTemplate(plusMillis, plusMillisTemplate)); - add(new MethodTemplate(minusLong, minusMillisTemplate)); - add(new MethodTemplate(minusReadableDuration, minusReadableDurationTemplate)); - add(new MethodTemplate(minusYears, minusYearsTemplate)); - add(new MethodTemplate(minusMonths, minusMonthsTemplate)); - add(new MethodTemplate(minusWeeks, minusWeeksTemplate)); - add(new MethodTemplate(minusDays, minusDaysTemplate)); - add(new MethodTemplate(minusHours, minusHoursTemplate)); - add(new MethodTemplate(minusMinutes, minusMinutesTemplate)); - add(new MethodTemplate(minusSeconds, minusSecondsTemplate)); - add(new MethodTemplate(minusMillis, minusMillisTemplate)); - add(new MethodTemplate(toLocalDateTime, toLocalDateTimeTemplate)); - add(new MethodTemplate(toLocalDate, toLocalDateTemplate)); - add(new MethodTemplate(toLocalTime, toLocalTimeTemplate)); - add(new MethodTemplate(withYear, withYearTemplate)); - add(new MethodTemplate(withWeekyear, withWeekyearTemplate)); - add(new MethodTemplate(withMonthOfYear, withMonthOfYearTemplate)); - add(new MethodTemplate(withWeekOfWeekyear, withWeekOfWeekyearTemplate)); - add(new MethodTemplate(withDayOfYear, withDayOfYearTemplate)); - add(new MethodTemplate(withDayOfMonth, withDayOfMonthTemplate)); - add(new MethodTemplate(withDayOfWeek, withDayOfWeekTemplate)); - add(new MethodTemplate(withHourOfDay, withHourOfDayTemplate)); - add(new MethodTemplate(withMinuteOfHour, withMinuteOfHourTemplate)); - add(new MethodTemplate(withSecondOfMinute, withSecondOfMinuteTemplate)); - add(new MethodTemplate(withMillisOfSecond, withMillisOfSecondTemplate)); - add(new MethodTemplate(withMillisOfDay, withMillisOfDayTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DurationTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DurationTemplates.java deleted file mode 100644 index 96de8caf30..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/DurationTemplates.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; -import org.openrewrite.java.tree.Expression; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -@NoArgsConstructor -public class DurationTemplates implements Templates { - private final MethodMatcher parse = new MethodMatcher(JODA_DURATION + " parse(String)"); - private final MethodMatcher standardDays = new MethodMatcher(JODA_DURATION + " standardDays(long)"); - private final MethodMatcher standardHours = new MethodMatcher(JODA_DURATION + " standardHours(long)"); - private final MethodMatcher standardMinutes = new MethodMatcher(JODA_DURATION + " standardMinutes(long)"); - private final MethodMatcher standardSeconds = new MethodMatcher(JODA_DURATION + " standardSeconds(long)"); - private final MethodMatcher millis = new MethodMatcher(JODA_DURATION + " millis(long)"); - - private final MethodMatcher newDuration = new MethodMatcher(JODA_DURATION + "(long)"); - private final MethodMatcher newDurationWithInstants = new MethodMatcher(JODA_DURATION + "(long,long)"); - - private final MethodMatcher getStandardDays = new MethodMatcher(JODA_DURATION + " getStandardDays()"); - private final MethodMatcher getStandardHours = new MethodMatcher(JODA_DURATION + " getStandardHours()"); - private final MethodMatcher getStandardMinutes = new MethodMatcher(JODA_DURATION + " getStandardMinutes()"); - private final MethodMatcher getStandardSeconds = new MethodMatcher(JODA_DURATION + " getStandardSeconds()"); - - private final MethodMatcher toDuration = new MethodMatcher(JODA_DURATION + " toDuration()"); - - private final MethodMatcher toStandardDays = new MethodMatcher(JODA_DURATION + " toStandardDays()"); - private final MethodMatcher toStandardHours = new MethodMatcher(JODA_DURATION + " toStandardHours()"); - private final MethodMatcher toStandardMinutes = new MethodMatcher(JODA_DURATION + " toStandardMinutes()"); - private final MethodMatcher toStandardSeconds = new MethodMatcher(JODA_DURATION + " toStandardSeconds()"); - - private final MethodMatcher withMillis = new MethodMatcher(JODA_DURATION + " withMillis(long)"); - private final MethodMatcher withDurationAdded = new MethodMatcher(JODA_DURATION + " withDurationAdded(long,int)"); - private final MethodMatcher withDurationAddedReadable = new MethodMatcher(JODA_DURATION + " withDurationAdded(" + JODA_READABLE_DURATION + ",int)"); - - private final MethodMatcher plusLong = new MethodMatcher(JODA_DURATION + " plus(long)"); - private final MethodMatcher plusReadable = new MethodMatcher(JODA_DURATION + " plus(" + JODA_READABLE_DURATION + ")"); - private final MethodMatcher minusLong = new MethodMatcher(JODA_DURATION + " minus(long)"); - private final MethodMatcher minusReadable = new MethodMatcher(JODA_DURATION + " minus(" + JODA_READABLE_DURATION + ")"); - - private final MethodMatcher multipliedBy = new MethodMatcher(JODA_DURATION + " multipliedBy(long)"); - private final MethodMatcher dividedBy = new MethodMatcher(JODA_DURATION + " dividedBy(long)"); - - private final MethodMatcher negated = new MethodMatcher(JODA_DURATION + " negated()"); - private final MethodMatcher abs = new MethodMatcher(JODA_DURATION + " abs()"); - - private final JavaTemplate parseTemplate = JavaTemplate.builder("Duration.parse(#{any(String)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate standardDaysTemplate = JavaTemplate.builder("Duration.ofDays(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate standardHoursTemplate = JavaTemplate.builder("Duration.ofHours(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate standardMinutesTemplate = JavaTemplate.builder("Duration.ofMinutes(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate standardSecondsTemplate = JavaTemplate.builder("Duration.ofSeconds(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate millisTemplate = JavaTemplate.builder("Duration.ofMillis(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - - private final JavaTemplate newDurationTemplate = JavaTemplate.builder("Duration.ofMillis(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate newDurationWithInstantsTemplate = JavaTemplate.builder("Duration.between(Instant.ofEpochMilli(#{any(long)}), Instant.ofEpochMilli(#{any(long)}))") - .imports(JAVA_DURATION, JAVA_INSTANT) - .build(); - private final JavaTemplate toDurationTemplate = JavaTemplate.builder("#{any(java.time.Duration)}") - .build(); - private final JavaTemplate toDaysTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toDays()") - .build(); - private final JavaTemplate toHoursTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toHours()") - .build(); - private final JavaTemplate toMinutesTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toMinutes()") - .build(); - private final JavaTemplate getSecondsTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.getSeconds()") - .build(); - private final JavaTemplate ofMillisTemplate = JavaTemplate.builder("Duration.ofMillis(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate withDurationAddedTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plusMillis(#{any(long)} * #{any(int)})") - .build(); - private final JavaTemplate withDurationAddedReadableTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plus(#{any(java.time.Duration)}.multipliedBy(#{any(int)}))") - .build(); - private final JavaTemplate plusLongTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plusMillis(#{any(long)})") - .build(); - private final JavaTemplate plusReadableTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plus(#{any(java.time.Duration)})") - .build(); - private final JavaTemplate minusLongTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minusMillis(#{any(long)})") - .build(); - private final JavaTemplate minusReadableTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)})") - .build(); - private final JavaTemplate multipliedByTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.multipliedBy(#{any(long)})") - .build(); - private final JavaTemplate dividedByTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.dividedBy(#{any(long)})") - .build(); - private final JavaTemplate negatedTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.negated()") - .build(); - private final JavaTemplate absTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.abs()") - .build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(parse, parseTemplate)); - add(new MethodTemplate(standardDays, standardDaysTemplate)); - add(new MethodTemplate(standardHours, standardHoursTemplate)); - add(new MethodTemplate(standardMinutes, standardMinutesTemplate)); - add(new MethodTemplate(standardSeconds, standardSecondsTemplate)); - add(new MethodTemplate(millis, millisTemplate)); - - add(new MethodTemplate(newDuration, newDurationTemplate)); - add(new MethodTemplate(newDurationWithInstants, newDurationWithInstantsTemplate)); - - add(new MethodTemplate(getStandardDays, toDaysTemplate)); - add(new MethodTemplate(getStandardHours, toHoursTemplate)); - add(new MethodTemplate(getStandardMinutes, toMinutesTemplate)); - add(new MethodTemplate(getStandardSeconds, getSecondsTemplate)); - - add(new MethodTemplate(toDuration, toDurationTemplate)); - - add(new MethodTemplate(toStandardDays, toDaysTemplate)); - add(new MethodTemplate(toStandardHours, toHoursTemplate)); - add(new MethodTemplate(toStandardMinutes, toMinutesTemplate)); - add(new MethodTemplate(toStandardSeconds, getSecondsTemplate)); - - add(new MethodTemplate(withMillis, ofMillisTemplate, m -> new Expression[]{m.getArguments().get(0)})); - add(new MethodTemplate(withDurationAdded, withDurationAddedTemplate)); - add(new MethodTemplate(withDurationAddedReadable, withDurationAddedReadableTemplate)); - - add(new MethodTemplate(plusLong, plusLongTemplate)); - add(new MethodTemplate(plusReadable, plusReadableTemplate)); - add(new MethodTemplate(minusLong, minusLongTemplate)); - add(new MethodTemplate(minusReadable, minusReadableTemplate)); - - add(new MethodTemplate(multipliedBy, multipliedByTemplate)); - add(new MethodTemplate(dividedBy, dividedByTemplate)); - - add(new MethodTemplate(negated, negatedTemplate)); - add(new MethodTemplate(abs, absTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/InstantTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/InstantTemplates.java deleted file mode 100644 index 49e07b7688..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/InstantTemplates.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_INSTANT; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_INSTANT; - -public class InstantTemplates implements Templates { - private final MethodMatcher constructor = new MethodMatcher(JODA_INSTANT + " ()"); - private final MethodMatcher getMillis = new MethodMatcher(JODA_INSTANT + " getMillis()"); - private final MethodMatcher minusDuration = new MethodMatcher(JODA_INSTANT + " minus(org.joda.time.ReadableDuration)"); - private final MethodMatcher now = new MethodMatcher(JODA_INSTANT + " now()"); - private final MethodMatcher ofEpochMilli = new MethodMatcher(JODA_INSTANT + " ofEpochMilli(long)"); - private final MethodMatcher parse = new MethodMatcher(JODA_INSTANT + " parse(java.lang.String)"); - private final MethodMatcher plusDuration = new MethodMatcher(JODA_INSTANT + " plus(org.joda.time.ReadableDuration)"); - - private final JavaTemplate constructorTemplate = JavaTemplate.builder("Instant.now()") - .imports(JAVA_INSTANT).build(); - private final JavaTemplate getMillisTemplate = JavaTemplate.builder("#{any(" + JAVA_INSTANT + ")}.toEpochMilli()").build(); - private final JavaTemplate minusDurationTemplate = JavaTemplate.builder("#{any(" + JAVA_INSTANT + ")}.minus(#{any(java.time.Duration)})").build(); - private final JavaTemplate nowTemplate = JavaTemplate.builder("Instant.now()") - .imports(JAVA_INSTANT).build(); - private final JavaTemplate ofEpochMilliTemplate = JavaTemplate.builder("Instant.ofEpochMilli(#{any(long)})") - .imports(JAVA_INSTANT).build(); - private final JavaTemplate parseTemplate = JavaTemplate.builder("Instant.parse(#{any(java.lang.String)})") - .imports(JAVA_INSTANT).build(); - private final JavaTemplate plusDurationTemplate = JavaTemplate.builder("#{any(" + JAVA_INSTANT + ")}.plus(#{any(java.time.Duration)})").build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(constructor, constructorTemplate)); - add(new MethodTemplate(getMillis, getMillisTemplate)); - add(new MethodTemplate(getMillis, getMillisTemplate)); - add(new MethodTemplate(minusDuration, minusDurationTemplate)); - add(new MethodTemplate(now, nowTemplate)); - add(new MethodTemplate(ofEpochMilli, ofEpochMilliTemplate)); - add(new MethodTemplate(parse, parseTemplate)); - add(new MethodTemplate(plusDuration, plusDurationTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/IntervalTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/IntervalTemplates.java deleted file mode 100644 index fb139a5de4..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/IntervalTemplates.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaParser; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; -import org.openrewrite.java.tree.Expression; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -public class IntervalTemplates implements Templates { - private final MethodMatcher interval = new MethodMatcher(JODA_INTERVAL + " (long, long)"); - private final MethodMatcher intervalWithTimeZone = new MethodMatcher(JODA_INTERVAL + " (long, long, " + JODA_DATE_TIME_ZONE + ")"); - private final MethodMatcher intervalWithDateTime = new MethodMatcher(JODA_INTERVAL + " (" + JODA_READABLE_INSTANT + ", " + JODA_READABLE_INSTANT + ")"); - private final MethodMatcher intervalWithDateTimeAndDuration = new MethodMatcher(JODA_INTERVAL + " (" + JODA_READABLE_INSTANT + ", " + JODA_READABLE_DURATION + ")"); - - private final JavaTemplate intervalTemplate = JavaTemplate.builder("Interval.of(Instant.ofEpochMilli(#{any(long)}), Instant.ofEpochMilli(#{any(long)}))") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(JAVA_INSTANT, THREE_TEN_EXTRA_INTERVAL) - .build(); - private final JavaTemplate intervalWithDateTimeTemplate = JavaTemplate.builder("Interval.of(#{any(" + JAVA_DATE_TIME + ")}.toInstant(), #{any(" + JAVA_DATE_TIME + ")}.toInstant())") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(THREE_TEN_EXTRA_INTERVAL) - .build(); - private final JavaTemplate intervalWithDateTimeAndDurationTemplate = JavaTemplate.builder("Interval.of(#{any(" + JAVA_DATE_TIME + ")}.toInstant(), #{any(" + JAVA_DURATION + ")})") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(THREE_TEN_EXTRA_INTERVAL) - .build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(interval, intervalTemplate)); - add(new MethodTemplate(intervalWithTimeZone, intervalTemplate, - m -> new Expression[]{m.getArguments().get(0), m.getArguments().get(1)})); - add(new MethodTemplate(intervalWithDateTime, intervalWithDateTimeTemplate)); - add(new MethodTemplate(intervalWithDateTimeAndDuration, intervalWithDateTimeAndDurationTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/MethodTemplate.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/MethodTemplate.java deleted file mode 100644 index 77be5a63b6..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/MethodTemplate.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Value; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; -import org.openrewrite.java.tree.Expression; -import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.MethodCall; - -import java.util.function.Function; - -@Value -public class MethodTemplate { - MethodMatcher matcher; - JavaTemplate template; - Function templateArgsFunc; - - public MethodTemplate(MethodMatcher matcher, JavaTemplate template) { - this(matcher, template, m -> { - Expression select = isInstanceCall(m) ? ((J.MethodInvocation) m).getSelect() : null; - - if (m.getArguments().isEmpty() || m.getArguments().get(0) instanceof J.Empty) { - return select != null ? new Expression[]{select} : new Expression[0]; - } - - Expression[] args = m.getArguments().toArray(new Expression[0]); - if (select != null) { - Expression[] newArgs = new Expression[args.length + 1]; - newArgs[0] = select; - System.arraycopy(args, 0, newArgs, 1, args.length); - return newArgs; - } - return args; - }); - } - - public MethodTemplate(MethodMatcher matcher, JavaTemplate template, Function templateArgsFunc) { - this.matcher = matcher; - this.template = template; - this.templateArgsFunc = templateArgsFunc; - } - - private static boolean isInstanceCall(MethodCall m) { - if (!(m instanceof J.MethodInvocation)) { - return false; - } - J.MethodInvocation mi = (J.MethodInvocation) m; - if (mi.getSelect() instanceof J.FieldAccess) { - return ((J.FieldAccess) mi.getSelect()).getName().getFieldType() != null; - } - if (mi.getSelect() instanceof J.Identifier) { - return ((J.Identifier) mi.getSelect()).getFieldType() != null; - } - return true; - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/Templates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/Templates.java deleted file mode 100644 index aa2cf39d0a..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/Templates.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import org.openrewrite.java.tree.MethodCall; - -import java.util.List; - -public interface Templates { - List getTemplates(); - - /** - * This method is used to disambiguate between multiple potential template matches for a given methodCall. - * This should be overridden by Templates classes where methodMatcher.matches() may return more than one template. - **/ - default boolean matchesMethodCall(MethodCall method, MethodTemplate template) { - return true; - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassMap.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassMap.java deleted file mode 100644 index 06437dea14..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassMap.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import org.jspecify.annotations.Nullable; -import org.openrewrite.java.tree.JavaType; - -import java.util.HashMap; -import java.util.Map; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -public class TimeClassMap { - - private static final JavaType.Class object = JavaType.ShallowClass.build("java.lang.Object"); - - private final Map jodaToJavaTimeMap = new HashMap() { - { - put(JODA_DATE_TIME, javaTypeClass(JAVA_DATE_TIME, object)); - put(JODA_BASE_DATE_TIME, javaTypeClass(JAVA_DATE_TIME, object)); - put(JODA_DATE_TIME_ZONE, javaTypeClass(JAVA_ZONE_ID, object)); - put(JODA_TIME_FORMATTER, javaTypeClass(JAVA_TIME_FORMATTER, object)); - put(JODA_DURATION, javaTypeClass(JAVA_DURATION, object)); - put(JODA_READABLE_DURATION, javaTypeClass(JAVA_DURATION, object)); - put(JODA_INTERVAL, javaTypeClass(THREE_TEN_EXTRA_INTERVAL, object)); - } - }; - - private final Map jodaToJavaTimeShortName = new HashMap() { - { - put(JODA_DATE_TIME, "ZonedDateTime"); - } - }; - - private static JavaType.Class javaTypeClass(String fqn, JavaType.Class superType) { - return new JavaType.Class(null, 0, fqn, JavaType.FullyQualified.Kind.Class, null, superType, - null, null, null, null, null); - } - - public static JavaType.@Nullable Class getJavaTimeType(String typeFqn) { - return new TimeClassMap().jodaToJavaTimeMap.get(typeFqn); - } - - public static @Nullable String getJavaTimeShortName(String typeFqn) { - return new TimeClassMap().jodaToJavaTimeShortName.get(typeFqn); - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassNames.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassNames.java deleted file mode 100644 index 4cb88c0554..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassNames.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import java.util.regex.Pattern; - -public class TimeClassNames { - public static final Pattern JODA_CLASS_PATTERN = Pattern.compile("org\\.joda\\.time\\..*"); - - // java util - public static final String JAVA_UTIL_DATE = "java.util.Date"; - - // Joda-Time classes - public static final String JODA_TIME_PKG = "org.joda.time"; - public static final String JODA_ABSTRACT_DATE_TIME = JODA_TIME_PKG + ".base.AbstractDateTime"; - public static final String JODA_ABSTRACT_DURATION = JODA_TIME_PKG + ".base.AbstractDuration"; - public static final String JODA_ABSTRACT_INTERVAL = JODA_TIME_PKG + ".base.AbstractInterval"; - public static final String JODA_BASE_DATE_TIME = JODA_TIME_PKG + ".base.BaseDateTime"; - public static final String JODA_DATE_TIME = JODA_TIME_PKG + ".DateTime"; - public static final String JODA_DATE_TIME_ZONE = JODA_TIME_PKG + ".DateTimeZone"; - public static final String JODA_TIME_FORMAT = JODA_TIME_PKG + ".format.DateTimeFormat"; - public static final String JODA_TIME_FORMATTER = JODA_TIME_PKG + ".format.DateTimeFormatter"; - public static final String JODA_LOCAL_DATE = JODA_TIME_PKG + ".LocalDate"; - public static final String JODA_LOCAL_TIME = JODA_TIME_PKG + ".LocalTime"; - public static final String JODA_DATE_TIME_FIELD_TYPE = JODA_TIME_PKG + ".DateTimeFieldType"; - public static final String JODA_DURATION_FIELD_TYPE = JODA_TIME_PKG + ".DurationFieldType"; - public static final String JODA_DURATION = JODA_TIME_PKG + ".Duration"; - public static final String JODA_READABLE_DURATION = JODA_TIME_PKG + ".ReadableDuration"; - public static final String JODA_BASE_DURATION = JODA_TIME_PKG + ".base.BaseDuration"; - public static final String JODA_ABSTRACT_INSTANT = JODA_TIME_PKG + ".base.AbstractInstant"; - public static final String JODA_READABLE_INSTANT = JODA_TIME_PKG + ".ReadableInstant"; - public static final String JODA_INSTANT = JODA_TIME_PKG + ".Instant"; - public static final String JODA_INTERVAL = JODA_TIME_PKG + ".Interval"; - public static final String JODA_BASE_INTERVAL = JODA_TIME_PKG + ".base.BaseInterval"; - - // Java Time classes - public static final String JAVA_TIME_PKG = "java.time"; - public static final String JAVA_DATE_TIME = JAVA_TIME_PKG + ".ZonedDateTime"; - public static final String JAVA_DURATION = JAVA_TIME_PKG + ".Duration"; - public static final String JAVA_ZONE_OFFSET = JAVA_TIME_PKG + ".ZoneOffset"; - public static final String JAVA_ZONE_ID = JAVA_TIME_PKG + ".ZoneId"; - public static final String JAVA_INSTANT = JAVA_TIME_PKG + ".Instant"; - public static final String JAVA_TIME_FORMATTER = JAVA_TIME_PKG + ".format.DateTimeFormatter"; - public static final String JAVA_TIME_FORMAT_STYLE = JAVA_TIME_PKG + ".format.FormatStyle"; - public static final String JAVA_TEMPORAL_ADJUSTER = JAVA_TIME_PKG + ".temporal.TemporalAdjuster"; - public static final String JAVA_LOCAL_DATE = JAVA_TIME_PKG + ".LocalDate"; - public static final String JAVA_LOCAL_TIME = JAVA_TIME_PKG + ".LocalTime"; - public static final String JAVA_TEMPORAL_ISO_FIELDS = JAVA_TIME_PKG + ".temporal.IsoFields"; - public static final String JAVA_CHRONO_FIELD = JAVA_TIME_PKG + ".temporal.ChronoField"; - - // ThreeTen-Extra classes - public static final String THREE_TEN_EXTRA_PKG = "org.threeten.extra"; - public static final String THREE_TEN_EXTRA_INTERVAL = THREE_TEN_EXTRA_PKG + ".Interval"; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeZoneTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeZoneTemplates.java deleted file mode 100644 index b5ba559e66..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeZoneTemplates.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -public class TimeZoneTemplates implements Templates { - private final MethodMatcher zoneForID = new MethodMatcher(JODA_DATE_TIME_ZONE + " forID(String)"); - private final MethodMatcher zoneForOffsetHours = new MethodMatcher(JODA_DATE_TIME_ZONE + " forOffsetHours(int)"); - private final MethodMatcher zoneForOffsetHoursMinutes = new MethodMatcher(JODA_DATE_TIME_ZONE + " forOffsetHoursMinutes(int, int)"); - private final MethodMatcher zoneForTimeZone = new MethodMatcher(JODA_DATE_TIME_ZONE + " forTimeZone(java.util.TimeZone)"); - - private final JavaTemplate zoneIdOfTemplate = JavaTemplate.builder("ZoneId.of(#{any(String)})") - .imports(JAVA_ZONE_ID) - .build(); - private final JavaTemplate zoneOffsetHoursTemplate = JavaTemplate.builder("ZoneOffset.ofHours(#{any(int)})") - .imports(JAVA_ZONE_OFFSET) - .build(); - private final JavaTemplate zoneOffsetHoursMinutesTemplate = JavaTemplate.builder("ZoneOffset.ofHoursMinutes(#{any(int)}, #{any(int)})") - .imports(JAVA_ZONE_OFFSET) - .build(); - private final JavaTemplate timeZoneToZoneIdTemplate = JavaTemplate.builder("#{any(java.util.TimeZone)}.toZoneId()") - .build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(zoneForID, zoneIdOfTemplate)); - add(new MethodTemplate(zoneForOffsetHours, zoneOffsetHoursTemplate)); - add(new MethodTemplate(zoneForOffsetHoursMinutes, zoneOffsetHoursMinutesTemplate)); - add(new MethodTemplate(zoneForTimeZone, timeZoneToZoneIdTemplate)); - } - }; -} 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 deleted file mode 100644 index 0b5968beeb..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/VarTemplates.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda.templates; - -import org.openrewrite.java.JavaParser; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.tree.J; -import org.openrewrite.java.tree.JavaType; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -public class VarTemplates { - - private static Map JodaToJavaTimeType = new HashMap() { - { - put(JODA_DATE_TIME, JAVA_DATE_TIME); - put(JODA_TIME_FORMATTER, JAVA_TIME_FORMATTER); - put(JODA_LOCAL_DATE, JAVA_LOCAL_DATE); - put(JODA_LOCAL_TIME, JAVA_LOCAL_TIME); - put(JODA_DATE_TIME_ZONE, JAVA_ZONE_ID); - put(JODA_DURATION, JAVA_DURATION); - put(JODA_INTERVAL, THREE_TEN_EXTRA_INTERVAL); - } - }; - - 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 { - varName = Class.forName(typeName).getSimpleName(); - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Unknown type " + typeName); - } - template.append(varName); - template.append(" "); - for (int i = 0; i < variable.getVariables().size(); i++) { - if (i > 0) { - template.append(", "); - } - template.append("#{}"); - if (variable.getVariables().get(i).getInitializer() != null) { - template.append(" = #{any("); - template.append(typeName); - template.append(")}"); - } - } - return Optional.of(JavaTemplate.builder(template.toString()) - .imports(typeName) - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .build()); - } - - 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 Optional.of(JavaTemplate.builder(template).build()); - } - - public static Object[] getTemplateArgs(J.VariableDeclarations variable) { - Object[] args = new Object[variable.getVariables().size() * 2]; - int i = 0; - for (J.VariableDeclarations.NamedVariable var : variable.getVariables()) { - args[i++] = var.getSimpleName(); - if (var.getInitializer() != null) { - args[i++] = var.getInitializer(); - } - } - Object[] args2 = new Object[i]; - System.arraycopy(args, 0, args2, 0, i); - return args2; - } -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/package-info.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/package-info.java deleted file mode 100644 index c736551896..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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. - */ -@NullMarked -@NonNullFields -package org.openrewrite.java.migrate.joda.templates; - -import org.jspecify.annotations.NullMarked; -import org.openrewrite.internal.lang.NonNullFields; diff --git a/src/main/resources/META-INF/rewrite/examples.yml b/src/main/resources/META-INF/rewrite/examples.yml index d85099aadb..af428868b7 100644 --- a/src/main/resources/META-INF/rewrite/examples.yml +++ b/src/main/resources/META-INF/rewrite/examples.yml @@ -5828,100 +5828,6 @@ examples: language: java --- type: specs.openrewrite.org/v1beta/example -recipeName: org.openrewrite.java.migrate.joda.JodaTimeRecipe -examples: -- description: '' - sources: - - before: | - import org.joda.time.DateTime; - - class A { - public void foo() { - DateTime dt = new DateTime(); - System.out.println(dt.toDateTime()); - } - } - after: | - import java.time.ZonedDateTime; - - class A { - public void foo() { - ZonedDateTime dt = ZonedDateTime.now(); - System.out.println(dt); - } - } - language: java ---- -type: specs.openrewrite.org/v1beta/example -recipeName: org.openrewrite.java.migrate.joda.NoJodaTime -examples: -- description: '' - sources: - - before: | - import org.joda.time.DateTime; - import org.joda.time.Interval; - - class A { - void foo() { - DateTime dt = new DateTime(); - DateTime dt1 = new DateTime().plusDays(1); - Interval i = new Interval(dt, dt1); - System.out.println(i.toDuration()); - } - } - after: | - import org.threeten.extra.Interval; - - import java.time.ZonedDateTime; - - class A { - void foo() { - ZonedDateTime dt = ZonedDateTime.now(); - ZonedDateTime dt1 = ZonedDateTime.now().plusDays(1); - Interval i = Interval.of(dt.toInstant(), dt1.toInstant()); - System.out.println(i.toDuration()); - } - } - language: java - - before: foo - language: mavenProject - - before: | - - 4.0.0 - com.example.foobar - foobar-core - 1.0.0 - - - joda-time - joda-time - 2.12.3 - - - - after: | - - 4.0.0 - com.example.foobar - foobar-core - 1.0.0 - - - joda-time - joda-time - 2.12.3 - - - org.threeten - threeten-extra - 1.8.0 - - - - path: pom.xml - language: xml ---- -type: specs.openrewrite.org/v1beta/example recipeName: org.openrewrite.java.migrate.lang.ExplicitRecordImport examples: - description: '' diff --git a/src/main/resources/META-INF/rewrite/no-joda-time.yml b/src/main/resources/META-INF/rewrite/no-joda-time.yml deleted file mode 100644 index 1828004ed4..0000000000 --- a/src/main/resources/META-INF/rewrite/no-joda-time.yml +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright 2024 the original author or authors. -#

-# Licensed under the Moderne Source Available License (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -#

-# https://docs.moderne.io/licensing/moderne-source-available-license -#

-# 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. -# - ---- -type: specs.openrewrite.org/v1beta/recipe -name: org.openrewrite.java.migrate.joda.NoJodaTime -displayName: Prefer the Java standard library instead of Joda-Time -description: >- - Before Java 8, Java lacked a robust date and time library, leading to the widespread use of Joda-Time to fill this - gap. With the release of Java 8, the `java.time` package was introduced, incorporating most of Joda-Time's concepts. - Features deemed too specialized or bulky for `java.time` were included in the ThreeTen-Extra library. This recipe - migrates Joda-Time types to `java.time` and `threeten-extra` types. -tags: - - joda-time -recipeList: - - org.openrewrite.java.dependencies.AddDependency: - groupId: org.threeten - artifactId: threeten-extra - version: 1.8.0 - onlyIfUsing: org.joda.time.*Interval* - - org.openrewrite.java.migrate.joda.JodaTimeRecipe diff --git a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeFlowSpecTest.java b/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeFlowSpecTest.java deleted file mode 100644 index 66949495d1..0000000000 --- a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeFlowSpecTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; -import org.openrewrite.Cursor; -import org.openrewrite.DocumentExample; -import org.openrewrite.ExecutionContext; -import org.openrewrite.analysis.dataflow.Dataflow; -import org.openrewrite.java.JavaIsoVisitor; -import org.openrewrite.java.JavaParser; -import org.openrewrite.java.tree.Expression; -import org.openrewrite.java.tree.J; -import org.openrewrite.marker.SearchResult; -import org.openrewrite.test.RecipeSpec; -import org.openrewrite.test.RewriteTest; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static java.util.stream.Collectors.joining; -import static org.openrewrite.java.Assertions.java; -import static org.openrewrite.test.RewriteTest.toRecipe; - -@Execution(ExecutionMode.SAME_THREAD) -class JodaTimeFlowSpecTest implements RewriteTest { - @Override - public void defaults(RecipeSpec spec) { - spec - .recipe(toRecipe(() -> new JavaIsoVisitor<>() { - Map> exprVarBindings = new HashMap<>(); - - @Override - public J.VariableDeclarations.NamedVariable visitVariable(J.VariableDeclarations.NamedVariable variable, ExecutionContext ctx) { - if (atMethodParam(getCursor())) { - updateSinks(getCursor(), variable.getName()); - } - if (variable.getInitializer() != null) { - updateSinks(new Cursor(getCursor(), variable.getInitializer()), variable.getName()); - } - return super.visitVariable(variable, ctx); - } - - @Override - public J.Assignment visitAssignment(J.Assignment assignment, ExecutionContext ctx) { - if (!(assignment.getVariable() instanceof J.Identifier)) { - return super.visitAssignment(assignment, ctx); - } - Cursor cursor = new Cursor(getCursor(), assignment.getAssignment()); - updateSinks(cursor, (J.Identifier) assignment.getVariable()); - return super.visitAssignment(assignment, ctx); - } - - @Override - public Expression visitExpression(Expression expression, ExecutionContext ctx) { - List identifiers = exprVarBindings.get(expression); - if (identifiers == null || identifiers.isEmpty()) { - return expression; - } - String desc = identifiers.stream().map(J.Identifier::getSimpleName).collect(joining(", ")); - return SearchResult.found(expression, desc); - } - - private void updateSinks(Cursor cursor, J.Identifier identifier) { - Dataflow.startingAt(cursor).findSinks(new JodaTimeFlowSpec()) - .foreachDoEffect(sinkFlow -> { - for (Expression sink : sinkFlow.getExpressionSinks()) { - exprVarBindings.computeIfAbsent(sink, e -> new ArrayList<>()).add(identifier); - } - }); - } - - private boolean atMethodParam(Cursor cursor) { - return cursor.getParentTreeCursor().getParentTreeCursor().getValue() instanceof J.MethodDeclaration; - } - })) - .parser(JavaParser.fromJavaVersion().classpath("joda-time")); - } - - @DocumentExample - @Test - void jodaTimeUsageWithVarBindings() { - rewriteRun( - // language=java - java( - """ - import org.joda.time.DateTime; - import org.joda.time.Interval; - - class A { - public void foo() { - DateTime dateTime = new DateTime(), _dateTime = DateTime.now(); - System.out.println(dateTime); - DateTime dateTimePlus2 = dateTime.plusDays(2); - System.out.println(dateTimePlus2); - dateTime = dateTime.minusDays(1); - _dateTime = dateTime; - Interval interval = new Interval(_dateTime, dateTimePlus2); - print(interval); - } - private void print(Interval interval) { - System.out.println(interval); - } - } - """, - """ - import org.joda.time.DateTime; - import org.joda.time.Interval; - - class A { - public void foo() { - DateTime dateTime = /*~~(dateTime)~~>*/new DateTime(), _dateTime = /*~~(_dateTime)~~>*/DateTime.now(); - System.out.println(/*~~(dateTime)~~>*/dateTime); - DateTime dateTimePlus2 = /*~~(dateTimePlus2)~~>*//*~~(dateTime)~~>*/dateTime.plusDays(2); - System.out.println(/*~~(dateTimePlus2)~~>*/dateTimePlus2); - dateTime = /*~~(dateTime)~~>*//*~~(dateTime)~~>*/dateTime.minusDays(1); - _dateTime = /*~~(dateTime, _dateTime)~~>*/dateTime; - Interval interval = /*~~(interval)~~>*/new Interval(/*~~(dateTime, _dateTime)~~>*/_dateTime, /*~~(dateTimePlus2)~~>*/dateTimePlus2); - print(/*~~(interval)~~>*/interval); - } - private void print(Interval interval) { - System.out.println(/*~~(interval)~~>*/interval); - } - } - """ - ) - ); - } -} diff --git a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeRecipeTest.java b/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeRecipeTest.java deleted file mode 100644 index b5b6504980..0000000000 --- a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeRecipeTest.java +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; -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; - -@Execution(ExecutionMode.SAME_THREAD) -class JodaTimeRecipeTest implements RewriteTest { - @Override - public void defaults(RecipeSpec spec) { - spec - .recipe(new JodaTimeRecipe()) - .parser(JavaParser.fromJavaVersion().classpath("joda-time")); - } - - @DocumentExample - @Test - void migrateSafeVariable() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - - class A { - public void foo() { - DateTime dt = new DateTime(); - System.out.println(dt.toDateTime()); - } - } - """, - """ - import java.time.ZonedDateTime; - - class A { - public void foo() { - ZonedDateTime dt = ZonedDateTime.now(); - System.out.println(dt); - } - } - """ - ) - ); - } - - @Test - void dontChangeClassVariable() { - // not supported yet - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - - class A { - public void foo() { - DateTime dt = new DateTime(); - System.out.println(dt.toDateTime()); - System.out.println(new B().dateTime.toDateTime()); - } - public static class B { - DateTime dateTime = new DateTime(); - } - } - """, - """ - import org.joda.time.DateTime; - - import java.time.ZonedDateTime; - - class A { - public void foo() { - ZonedDateTime dt = ZonedDateTime.now(); - System.out.println(dt); - System.out.println(new B().dateTime.toDateTime()); - } - public static class B { - DateTime dateTime = new DateTime(); - } - } - """ - ) - ); - } - - @Test - void safeMethodParamMigrationAcrossClassBoundary() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - - class A { - public void foo() { - new B().print(new DateTime()); - System.out.println(new B().dateTime); // dateTime is class variable, not handled yet - } - } - - class B { - DateTime dateTime = new DateTime(); - public void print(DateTime dateTime) { - System.out.println(dateTime); - } - } - """, - """ - import org.joda.time.DateTime; - - import java.time.ZonedDateTime; - - class A { - public void foo() { - new B().print(ZonedDateTime.now()); - System.out.println(new B().dateTime); // dateTime is class variable, not handled yet - } - } - - class B { - DateTime dateTime = new DateTime(); - public void print(ZonedDateTime dateTime) { - System.out.println(dateTime); - } - } - """ - ) - ); - } - - @Test - void noUnsafeVar() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.DateTimeZone; - import java.util.Date; - - class A { - public void foo(String city) { - DateTimeZone dtz; - if ("london".equals(city)) { - dtz = DateTimeZone.forID("Europe/London"); - } else { - dtz = DateTimeZone.forID("America/New_York"); - } - DateTime dt = new DateTime(dtz); - print(dt.toDate()); - } - private void print(Date date) { - System.out.println(date); - } - } - """, - """ - import java.time.ZoneId; - import java.time.ZonedDateTime; - import java.util.Date; - - class A { - public void foo(String city) { - ZoneId dtz; - if ("london".equals(city)) { - dtz = ZoneId.of("Europe/London"); - } else { - dtz = ZoneId.of("America/New_York"); - } - ZonedDateTime dt = ZonedDateTime.now(dtz); - print(Date.from(dt.toInstant())); - } - private void print(Date date) { - System.out.println(date); - } - } - """ - ) - ); - } - - @Test - void localVarUsedReferencedInReturnStatement() { - // language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.DateTimeZone; - - class A { - public DateTime foo(String city) { - DateTimeZone dtz; - if ("london".equals(city)) { - dtz = DateTimeZone.forID("Europe/London"); - } else { - dtz = DateTimeZone.forID("America/New_York"); - } - DateTime dt = new DateTime(dtz); - return dt.plus(2); - } - } - """, - """ - import java.time.Duration; - import java.time.ZoneId; - import java.time.ZonedDateTime; - - class A { - public ZonedDateTime foo(String city) { - ZoneId dtz; - if ("london".equals(city)) { - dtz = ZoneId.of("Europe/London"); - } else { - dtz = ZoneId.of("America/New_York"); - } - ZonedDateTime dt = ZonedDateTime.now(dtz); - return dt.plus(Duration.ofMillis(2)); - } - } - """ - ) - ); - } - - @Test - void migrateSafeMethodParam() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - - class A { - public void foo() { - new Bar().bar(new DateTime()); - } - - private static class Bar { - public void bar(DateTime dt) { - dt.getMillis(); - } - } - } - """, - """ - import java.time.ZonedDateTime; - - class A { - public void foo() { - new Bar().bar(ZonedDateTime.now()); - } - - private static class Bar { - public void bar(ZonedDateTime dt) { - dt.toInstant().toEpochMilli(); - } - } - } - """ - ) - ); - } - - @Test - void migrationWithRecord() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - - record A(String x) { - public void foo() { - new Bar().bar(new DateTime()); - } - - private static class Bar { - public void bar(DateTime dt) { - dt.getMillis(); - } - } - } - """, - """ - import java.time.ZonedDateTime; - - record A(String x) { - public void foo() { - new Bar().bar(ZonedDateTime.now()); - } - - private static class Bar { - public void bar(ZonedDateTime dt) { - dt.toInstant().toEpochMilli(); - } - } - } - """ - ) - ); - } - - @Test - void migrateMethodWithSafeReturnExpression() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.Interval; - - class A { - public DateTime foo(DateTime dt) { - Interval interval = new Interval(dt, dt.plusDays(1)); - return interval.getEnd(); - } - - private static class Bar { - public void bar(DateTime dt) { - DateTime d = foo(dt); - System.out.println(d.getMillis()); - } - } - } - """, - """ - import org.threeten.extra.Interval; - - import java.time.ZoneId; - import java.time.ZonedDateTime; - - class A { - public ZonedDateTime foo(ZonedDateTime dt) { - Interval interval = Interval.of(dt.toInstant(), dt.plusDays(1).toInstant()); - return interval.getEnd().atZone(ZoneId.systemDefault()); - } - - private static class Bar { - public void bar(ZonedDateTime dt) { - ZonedDateTime d = foo(dt); - System.out.println(d.toInstant().toEpochMilli()); - } - } - } - """ - ) - ); - } - - @Test - void migrateMethodWithSafeReturnExpressionAndUnsafeParam() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.Interval; - - class A { - public DateTime foo(DateTime dt) { - DateTime d = dt.toDateMidnight(); - DateTime d2 = DateTime.now(); - Interval interval = new Interval(d2, d2.plusDays(1)); - return interval.getEnd(); - } - - private static class Bar { - public void bar() { - DateTime d = foo(new DateTime()); - System.out.println(d.getMillis()); - } - } - } - """, - """ - import org.joda.time.DateTime; - import org.threeten.extra.Interval; - - import java.time.ZoneId; - import java.time.ZonedDateTime; - - class A { - public ZonedDateTime foo(DateTime dt) { - DateTime d = dt.toDateMidnight(); - ZonedDateTime d2 = ZonedDateTime.now(); - Interval interval = Interval.of(d2.toInstant(), d2.plusDays(1).toInstant()); - return interval.getEnd().atZone(ZoneId.systemDefault()); - } - - private static class Bar { - public void bar() { - ZonedDateTime d = foo(new DateTime()); - System.out.println(d.toInstant().toEpochMilli()); - } - } - } - """ - ) - ); - } - - @Test - void doNotMigrateUnsafeMethodParam() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - - class A { - public void foo() { - new Bar().bar(new DateTime()); - } - - private static class Bar { - public void bar(DateTime dt) { - dt.toDateMidnight(); // template doesn't exist for toDateMidnight - } - } - } - """ - ) - ); - } - - @Test - void dontMigrateMethodInvocationIfSelectExprIsNotMigrated() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.Interval; - - class A { - private Query query = new Query(); - public void foo() { - query.interval().getEndMillis(); - } - static class Query { - private Interval interval; - - public Interval interval() { - return interval; - } - } - } - """ - ) - ); - } - - @Test - void migrateWithMethodReferenceInComment() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - - class A { - public void foo() { - /** - * some method reference in comment - * {@link java.util.List#add(DateTime)} - */ - System.out.println(new DateTime()); - } - } - """, - """ - import java.time.ZonedDateTime; - - class A { - public void foo() { - /** - * some method reference in comment - * {@link java.util.List#add(DateTime)} - */ - System.out.println(ZonedDateTime.now()); - } - } - """ - ) - ); - } -} diff --git a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeScannerTest.java b/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeScannerTest.java deleted file mode 100644 index dc5c926838..0000000000 --- a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeScannerTest.java +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; -import org.openrewrite.java.JavaParser; -import org.openrewrite.java.tree.J; -import org.openrewrite.test.RecipeSpec; -import org.openrewrite.test.RewriteTest; - -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.openrewrite.java.Assertions.java; -import static org.openrewrite.test.RewriteTest.toRecipe; - -@Execution(ExecutionMode.SAME_THREAD) -class JodaTimeScannerTest implements RewriteTest { - @Override - public void defaults(RecipeSpec spec) { - spec.parser(JavaParser.fromJavaVersion().classpath("joda-time")); - } - - @Test - void noUnsafeVar() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.DateTime; - import org.joda.time.DateTimeZone; - import java.util.Date; - - class A { - public void foo(String city) { - DateTimeZone dtz; - if ("london".equals(city)) { - dtz = DateTimeZone.forID("Europe/London"); - } else { - dtz = DateTimeZone.forID("America/New_York"); - } - DateTime dt = new DateTime(dtz); - print(dt.toDate()); - } - private void print(Date date) { - System.out.println(date); - } - } - """ - ) - ); - assertThat(scanner.getAcc().getUnsafeVars()).isEmpty(); - } - - @Test - void hasUnsafeVars() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.DateTime; - import org.joda.time.DateTimeZone; - - class A { - DateTime dateTime; // class Variable not handled yet - public void foo(String city) { - DateTimeZone dtz; - if ("london".equals(city)) { - dtz = DateTimeZone.forID("Europe/London"); - } else { - dtz = DateTimeZone.forID("America/New_York"); - } - dateTime = new DateTime(dtz); - print(dateTime.toDateTime()); - } - private void print(DateTime dt) { - System.out.println(dt); - } - } - """ - ) - ); - // The variable 'dtz' is unsafe due to the class variable 'dateTime'. - // The parameter 'dt' in the 'print' method is also unsafe because one of its method calls is unsafe. - assertThat(scanner.getAcc().getUnsafeVars()).hasSize(3); - for (J.VariableDeclarations.NamedVariable var : scanner.getAcc().getUnsafeVars()) { - assertThat("dtz".equals(var.getSimpleName()) || - "dt".equals(var.getSimpleName()) || - "dateTime".equals(var.getSimpleName())).isTrue(); - } - } - - @Test - void localVarReferencingClassVar() { // not supported yet - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.DateTime; - import org.joda.time.DateTimeZone; - - class A { - DateTime dateTime; - public void foo(String city) { - DateTimeZone dtz; - if ("london".equals(city)) { - dtz = DateTimeZone.forID("Europe/London"); - } else { - dtz = DateTimeZone.forID("America/New_York"); - } - DateTime dt = dateTime.minus(2); - System.out.println(dt); - } - } - """ - ) - ); - // The local variable dt is unsafe due to class var datetime. - assertThat(scanner.getAcc().getUnsafeVars()).hasSize(2); - for (J.VariableDeclarations.NamedVariable var : scanner.getAcc().getUnsafeVars()) { - assertThat("dateTime".equals(var.getSimpleName()) || "dt".equals(var.getSimpleName())).isTrue(); - } - } - - @Test - void localVarUsedReferencedInReturnStatement() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.DateTime; - import org.joda.time.DateTimeZone; - - class A { - public DateTime foo(String city) { - DateTimeZone dtz; - if ("london".equals(city)) { - dtz = DateTimeZone.forID("Europe/London"); - } else { - dtz = DateTimeZone.forID("America/New_York"); - } - DateTime dt = new DateTime(dtz); - return dt.plus(2); - } - } - """ - ) - ); - assertThat(scanner.getAcc().getUnsafeVars()).isEmpty(); - } - - @Test - void unsafeMethodParam() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.DateTime; - - class A { - public void foo() { - new Bar().bar(new DateTime()); - } - - private static class Bar { - public void bar(DateTime dt) { - dt.toDateMidnight(); - } - } - } - """ - ) - ); - // The bar method parameter dt is unsafe because migration of toDateMidnight() is not yet implemented. - assertThat(scanner.getAcc().getUnsafeVars()).hasSize(1); - for (J.VariableDeclarations.NamedVariable var : scanner.getAcc().getUnsafeVars()) { - assertThat(var.getSimpleName()).isEqualTo("dt"); - } - } - - @Test - void detectUnsafeVarsInInitializer() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.Period; - import java.util.stream.Collectors; - import java.util.stream.Stream; - import java.util.List; - - class A { - public Period period() { - return new Period(); - } - - public void foo() { - List list = Stream.of(1, 2, 3).peek(i -> { - Period p1 = period(); - Period p2 = new Period(i, 100); - if (p1 != null && p1.plus(p2).getDays() > 10) { - System.out.println("Hello world!"); - } - }).toList(); - } - } - """ - ) - ); - assertThat(scanner.getAcc().getUnsafeVars().stream().map(J.VariableDeclarations.NamedVariable::getSimpleName)) - .hasSize(2) - .containsExactlyInAnyOrder("p1", "p2"); - } - - @Test - void detectUnsafeVarsInChainedLambdaExpressions() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.Period; - import java.util.stream.Collectors; - import java.util.stream.Stream; - import java.util.List; - - class A { - public Period period() { - return new Period(); - } - - public void foo() { - List list = Stream.of(1, 2, 3).peek(i -> { - Period p1 = period(); - Period p2 = new Period(i, 100); - if (p1 != null && p1.plus(p2).getDays() > 10) { - System.out.println("Hello world!"); - } - }).peek(i -> { - Period p3 = period(); - Period p4 = new Period(i, 100); - if (p3 != null && p3.plus(p4).getDays() > 10) { - System.out.println("Hello world!"); - } - }).toList(); - } - } - """ - ) - ); - assertThat(scanner.getAcc().getUnsafeVars().stream().map(J.VariableDeclarations.NamedVariable::getSimpleName)) - .hasSize(4) - .containsExactlyInAnyOrder("p1", "p2", "p3", "p4"); - } - - @Test - void hasSafeMethods() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.DateTime; - - class A { - private DateTime dateTime() { - DateTime dt = new DateTime(); - return dt; - } - public void print() { - System.out.println(dateTime()); - } - } - """ - ) - ); - assertThat(scanner.getAcc().getSafeMethodMap()).hasSize(1); - assertThat(scanner.getAcc().getSafeMethodMap().entrySet().stream().filter(Map.Entry::getValue).map(e -> e.getKey().toString())) - .containsExactlyInAnyOrder("A{name=dateTime,return=org.joda.time.DateTime,parameters=[]}"); - assertThat(scanner.getAcc().getUnsafeVars()).isEmpty(); - } - - @Test - void methodInvocationBeforeDeclaration() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.DateTime; - - class A { - public void print() { - System.out.println(dateTime()); - } - private DateTime dateTime() { - DateTime dt = new DateTime(); - return dt; - } - } - """ - ) - ); - assertThat(scanner.getAcc().getSafeMethodMap()).hasSize(1); - assertThat(scanner.getAcc().getSafeMethodMap().entrySet().stream().filter(Map.Entry::getValue).map(e -> e.getKey().toString())) - .containsExactlyInAnyOrder("A{name=dateTime,return=org.joda.time.DateTime,parameters=[]}"); - assertThat(scanner.getAcc().getUnsafeVars()).isEmpty(); - } - - @Test - void safeMethodWithUnsafeParam() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.DateTime; - import org.joda.time.Period; - - class A { - private DateTime dateTime(Period period) { - DateTime dt = new DateTime(); - System.out.println(period); - return dt; - } - public void print() { - System.out.println(dateTime(new Period())); - } - } - """ - ) - ); - assertThat(scanner.getAcc().getSafeMethodMap()).hasSize(1); - assertThat(scanner.getAcc().getSafeMethodMap().entrySet().stream().filter(Map.Entry::getValue).map(e -> e.getKey().toString())) - .containsExactlyInAnyOrder("A{name=dateTime,return=org.joda.time.DateTime,parameters=[org.joda.time.Period]}"); - assertThat(scanner.getAcc().getUnsafeVars().stream().map(J.VariableDeclarations.NamedVariable::getSimpleName)) - .containsExactlyInAnyOrder("period"); - } - - @Test - void unsafeMethodDueToUnhandledUsage() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.DateTime; - - class A { - private DateTime dateTime() { - DateTime dt = new DateTime(); - return dt; - } - public void print() { - dateTime().toDateMidnight(); - } - } - """ - ) - ); - assertThat(scanner.getAcc().getSafeMethodMap()).hasSize(1); - assertThat(scanner.getAcc().getSafeMethodMap().entrySet().stream().filter(Map.Entry::getValue)).isEmpty(); - assertThat(scanner.getAcc().getUnsafeVars().stream().map(J.VariableDeclarations.NamedVariable::getSimpleName)) - .containsExactlyInAnyOrder("dt"); - } - - @Test - void unsafeMethodDueToIndirectUnhandledUsage() { - JodaTimeScanner scanner = new JodaTimeScanner(new JodaTimeRecipe.Accumulator()); - // language=java - rewriteRun( - spec -> spec.recipe(toRecipe(() -> scanner)), - java( - """ - import org.joda.time.DateTime; - - class A { - private DateTime dateTime() { - DateTime dt = new DateTime(); - return dt; - } - public void print() { - DateTime dt = dateTime(); - dt.toDateMidnight(); - } - } - """ - ) - ); - assertThat(scanner.getAcc().getSafeMethodMap()).hasSize(1); - assertThat(scanner.getAcc().getSafeMethodMap().entrySet().stream().filter(Map.Entry::getValue)).isEmpty(); - assertThat(scanner.getAcc().getUnsafeVars().stream().map(J.VariableDeclarations.NamedVariable::getSimpleName)) - .containsExactlyInAnyOrder("dt", "dt"); - } -} diff --git a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeVisitorTest.java b/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeVisitorTest.java deleted file mode 100644 index bce6fb2dd1..0000000000 --- a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeVisitorTest.java +++ /dev/null @@ -1,939 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; -import org.openrewrite.DocumentExample; -import org.openrewrite.java.JavaParser; -import org.openrewrite.test.RecipeSpec; -import org.openrewrite.test.RewriteTest; - -import java.util.LinkedList; - -import static org.openrewrite.java.Assertions.java; -import static org.openrewrite.test.RewriteTest.toRecipe; - -@Execution(ExecutionMode.SAME_THREAD) -class JodaTimeVisitorTest implements RewriteTest { - @Override - public void defaults(RecipeSpec spec) { - spec - .recipe(toRecipe(() -> new JodaTimeVisitor(new JodaTimeRecipe.Accumulator(), true, new LinkedList<>()))) - .parser(JavaParser.fromJavaVersion().classpath("joda-time", "threeten-extra")); - } - - @DocumentExample - @Test - void migrateNewDateTime() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.DateTimeZone; - import java.util.TimeZone; - - class A { - public void foo() { - System.out.println(new DateTime()); - System.out.println(new DateTime(DateTimeZone.UTC)); - System.out.println(new DateTime(1234567890L)); - System.out.println(new DateTime(1234567890L, DateTimeZone.forID("America/New_York"))); - System.out.println(new DateTime(2024, 9, 30, 12, 58)); - System.out.println(new DateTime(2024, 9, 30, 12, 58, DateTimeZone.forOffsetHours(2))); - System.out.println(new DateTime(2024, 9, 30, 13, 3, 15)); - System.out.println(new DateTime(2024, 9, 30, 13, 3, 15, DateTimeZone.forOffsetHoursMinutes(5, 30))); - System.out.println(new DateTime(2024, 9, 30, 13, 49, 15, 545)); - System.out.println(new DateTime(2024, 9, 30, 13, 49, 15, 545, DateTimeZone.forTimeZone(TimeZone.getTimeZone("America/New_York")))); - } - } - """, - """ - import java.time.Instant; - import java.time.ZoneId; - import java.time.ZoneOffset; - import java.time.ZonedDateTime; - import java.util.TimeZone; - - class A { - public void foo() { - System.out.println(ZonedDateTime.now()); - System.out.println(ZonedDateTime.now(ZoneOffset.UTC)); - System.out.println(ZonedDateTime.ofInstant(Instant.ofEpochMilli(1234567890L), ZoneId.systemDefault())); - System.out.println(ZonedDateTime.ofInstant(Instant.ofEpochMilli(1234567890L), ZoneId.of("America/New_York"))); - System.out.println(ZonedDateTime.of(2024, 9, 30, 12, 58, 0, 0, ZoneId.systemDefault())); - System.out.println(ZonedDateTime.of(2024, 9, 30, 12, 58, 0, 0, ZoneOffset.ofHours(2))); - System.out.println(ZonedDateTime.of(2024, 9, 30, 13, 3, 15, 0, ZoneId.systemDefault())); - System.out.println(ZonedDateTime.of(2024, 9, 30, 13, 3, 15, 0, ZoneOffset.ofHoursMinutes(5, 30))); - System.out.println(ZonedDateTime.of(2024, 9, 30, 13, 49, 15, 545 * 1_000_000, ZoneId.systemDefault())); - System.out.println(ZonedDateTime.of(2024, 9, 30, 13, 49, 15, 545 * 1_000_000, TimeZone.getTimeZone("America/New_York").toZoneId())); - } - } - """ - ) - ); - } - - @Test - void migrateDateTimeStaticCalls() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.DateTimeZone; - import org.joda.time.format.DateTimeFormat; - import java.util.TimeZone; - - class A { - public void foo() { - System.out.println(DateTime.now()); - System.out.println(DateTime.now(DateTimeZone.forTimeZone(TimeZone.getTimeZone("America/New_York")))); - System.out.println(DateTime.parse("2024-09-30T23:03:00.000Z")); - System.out.println(DateTime.parse("2024-09-30T23:03:00.000Z", DateTimeFormat.shortDate())); - } - } - """, - """ - import java.time.ZonedDateTime; - import java.time.format.DateTimeFormatter; - import java.time.format.FormatStyle; - import java.util.TimeZone; - - class A { - public void foo() { - System.out.println(ZonedDateTime.now()); - System.out.println(ZonedDateTime.now(TimeZone.getTimeZone("America/New_York").toZoneId())); - System.out.println(ZonedDateTime.parse("2024-09-30T23:03:00.000Z")); - System.out.println(ZonedDateTime.parse("2024-09-30T23:03:00.000Z", DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))); - } - } - """ - ) - ); - } - - @Test - void migrateDateTimeInstanceCalls() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.DateTimeZone; - import org.joda.time.Duration; - import java.util.TimeZone; - - class A { - public void foo() { - System.out.println(new DateTime().toDateTime()); - System.out.println(new DateTime().toDateTime(DateTimeZone.forTimeZone(TimeZone.getTimeZone("America/New_York")))); - System.out.println(new DateTime().withMillis(1234567890L)); - System.out.println(new DateTime().withZone(DateTimeZone.forID("America/New_York"))); - System.out.println(new DateTime().withZoneRetainFields(DateTimeZone.forID("America/New_York"))); - System.out.println(new DateTime().withEarlierOffsetAtOverlap()); - System.out.println(new DateTime().withLaterOffsetAtOverlap()); - System.out.println(new DateTime().withDate(2024, 9, 30)); - System.out.println(new DateTime().withTime(12, 58, 57, 550)); - System.out.println(new DateTime().withDurationAdded(1234567890L, 2)); - System.out.println(new DateTime().plus(1234567890L)); - System.out.println(new DateTime().plus(Duration.standardDays(1))); - System.out.println(new DateTime().plusYears(1)); - System.out.println(new DateTime().plusMonths(1)); - System.out.println(new DateTime().plusWeeks(1)); - System.out.println(new DateTime().plusDays(1)); - System.out.println(new DateTime().plusHours(1)); - System.out.println(new DateTime().plusMinutes(1)); - System.out.println(new DateTime().plusSeconds(1)); - System.out.println(new DateTime().plusMillis(1)); - System.out.println(new DateTime().minus(1234567890L)); - System.out.println(new DateTime().minus(Duration.standardDays(1))); - System.out.println(new DateTime().minusYears(1)); - System.out.println(new DateTime().minusMonths(1)); - System.out.println(new DateTime().minusWeeks(1)); - System.out.println(new DateTime().minusDays(1)); - System.out.println(new DateTime().minusHours(1)); - System.out.println(new DateTime().minusMinutes(1)); - System.out.println(new DateTime().minusSeconds(1)); - System.out.println(new DateTime().minusMillis(1)); - System.out.println(new DateTime().toLocalDateTime()); - System.out.println(new DateTime().toLocalDate()); - System.out.println(new DateTime().toLocalTime()); - System.out.println(new DateTime().withYear(2024)); - System.out.println(new DateTime().withWeekyear(2024)); - System.out.println(new DateTime().withMonthOfYear(9)); - System.out.println(new DateTime().withWeekOfWeekyear(39)); - System.out.println(new DateTime().withDayOfYear(273)); - System.out.println(new DateTime().withDayOfMonth(30)); - System.out.println(new DateTime().withDayOfWeek(1)); - System.out.println(new DateTime().withHourOfDay(12)); - System.out.println(new DateTime().withMinuteOfHour(58)); - System.out.println(new DateTime().withSecondOfMinute(57)); - System.out.println(new DateTime().withMillisOfSecond(550)); - System.out.println(new DateTime().withMillisOfDay(123456)); - System.out.println(new DateTime().withTimeAtStartOfDay()); - } - } - """, - """ - import java.time.Duration; - import java.time.Instant; - import java.time.ZoneId; - import java.time.ZonedDateTime; - import java.time.temporal.ChronoField; - import java.time.temporal.IsoFields; - import java.util.TimeZone; - - class A { - public void foo() { - System.out.println(ZonedDateTime.now()); - System.out.println(ZonedDateTime.now().withZoneSameInstant(TimeZone.getTimeZone("America/New_York").toZoneId())); - System.out.println(ZonedDateTime.ofInstant(Instant.ofEpochMilli(1234567890L), ZonedDateTime.now().getZone())); - System.out.println(ZonedDateTime.now().withZoneSameInstant(ZoneId.of("America/New_York"))); - System.out.println(ZonedDateTime.now().withZoneSameLocal(ZoneId.of("America/New_York"))); - System.out.println(ZonedDateTime.now().withEarlierOffsetAtOverlap()); - System.out.println(ZonedDateTime.now().withLaterOffsetAtOverlap()); - System.out.println(ZonedDateTime.now().withYear(2024).withMonth(9).withDayOfMonth(30)); - System.out.println(ZonedDateTime.now().withHour(12).withMinute(58).withSecond(57).withNano(550 * 1_000_000)); - System.out.println(ZonedDateTime.now().plus(Duration.ofMillis(1234567890L).multipliedBy(2))); - System.out.println(ZonedDateTime.now().plus(Duration.ofMillis(1234567890L))); - System.out.println(ZonedDateTime.now().plus(Duration.ofDays(1))); - System.out.println(ZonedDateTime.now().plusYears(1)); - System.out.println(ZonedDateTime.now().plusMonths(1)); - System.out.println(ZonedDateTime.now().plusWeeks(1)); - System.out.println(ZonedDateTime.now().plusDays(1)); - System.out.println(ZonedDateTime.now().plusHours(1)); - System.out.println(ZonedDateTime.now().plusMinutes(1)); - System.out.println(ZonedDateTime.now().plusSeconds(1)); - System.out.println(ZonedDateTime.now().plus(Duration.ofMillis(1))); - System.out.println(ZonedDateTime.now().minus(Duration.ofMillis(1234567890L))); - System.out.println(ZonedDateTime.now().minus(Duration.ofDays(1))); - System.out.println(ZonedDateTime.now().minusYears(1)); - System.out.println(ZonedDateTime.now().minusMonths(1)); - System.out.println(ZonedDateTime.now().minusWeeks(1)); - System.out.println(ZonedDateTime.now().minusDays(1)); - System.out.println(ZonedDateTime.now().minusHours(1)); - System.out.println(ZonedDateTime.now().minusMinutes(1)); - System.out.println(ZonedDateTime.now().minusSeconds(1)); - System.out.println(ZonedDateTime.now().minus(Duration.ofMillis(1))); - System.out.println(ZonedDateTime.now().toLocalDateTime()); - System.out.println(ZonedDateTime.now().toLocalDate()); - System.out.println(ZonedDateTime.now().toLocalTime()); - System.out.println(ZonedDateTime.now().withYear(2024)); - System.out.println(ZonedDateTime.now().with(IsoFields.WEEK_BASED_YEAR, 2024)); - System.out.println(ZonedDateTime.now().withMonth(9)); - System.out.println(ZonedDateTime.now().with(ChronoField.ALIGNED_WEEK_OF_YEAR, 39)); - System.out.println(ZonedDateTime.now().withDayOfYear(273)); - System.out.println(ZonedDateTime.now().withDayOfMonth(30)); - System.out.println(ZonedDateTime.now().with(ChronoField.DAY_OF_WEEK, 1)); - System.out.println(ZonedDateTime.now().withHour(12)); - System.out.println(ZonedDateTime.now().withMinute(58)); - System.out.println(ZonedDateTime.now().withSecond(57)); - System.out.println(ZonedDateTime.now().withNano(550 * 1_000_000)); - System.out.println(ZonedDateTime.now().with(ChronoField.MILLI_OF_DAY, 123456)); - System.out.println(ZonedDateTime.now().toLocalDate().atStartOfDay(ZonedDateTime.now().getZone())); - } - } - """ - ) - ); - } - - @Test - void migrateDateTimeZone() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTimeZone; - import java.util.TimeZone; - - class A { - public void foo() { - System.out.println(DateTimeZone.UTC); - System.out.println(DateTimeZone.forID("America/New_York")); - System.out.println(DateTimeZone.forOffsetHours(2)); - System.out.println(DateTimeZone.forOffsetHoursMinutes(5, 30)); - System.out.println(DateTimeZone.forTimeZone(TimeZone.getTimeZone("America/New_York"))); - } - } - """, - """ - import java.time.ZoneId; - import java.time.ZoneOffset; - import java.util.TimeZone; - - class A { - public void foo() { - System.out.println(ZoneOffset.UTC); - System.out.println(ZoneId.of("America/New_York")); - System.out.println(ZoneOffset.ofHours(2)); - System.out.println(ZoneOffset.ofHoursMinutes(5, 30)); - System.out.println(TimeZone.getTimeZone("America/New_York").toZoneId()); - } - } - """ - ) - ); - } - - @Test - void migrateDateTimeFormat() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.format.DateTimeFormat; - - class A { - public void foo() { - System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); - // System.out.println(DateTimeFormat.forStyle("SS")); unhandled case - // System.out.println(DateTimeFormat.patternForStyle("SS", Locale.US)); unhandled case - System.out.println(DateTimeFormat.shortDate()); - System.out.println(DateTimeFormat.mediumDate()); - System.out.println(DateTimeFormat.longDate()); - System.out.println(DateTimeFormat.fullDate()); - System.out.println(DateTimeFormat.shortTime()); - System.out.println(DateTimeFormat.mediumTime()); - System.out.println(DateTimeFormat.longTime()); - System.out.println(DateTimeFormat.fullTime()); - System.out.println(DateTimeFormat.shortDateTime()); - System.out.println(DateTimeFormat.mediumDateTime()); - System.out.println(DateTimeFormat.longDateTime()); - System.out.println(DateTimeFormat.fullDateTime()); - } - } - """, - """ - import java.time.format.DateTimeFormatter; - import java.time.format.FormatStyle; - - class A { - public void foo() { - System.out.println(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); - // System.out.println(DateTimeFormat.forStyle("SS")); unhandled case - // System.out.println(DateTimeFormat.patternForStyle("SS", Locale.US)); unhandled case - System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)); - System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)); - System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)); - System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)); - System.out.println(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)); - System.out.println(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM)); - System.out.println(DateTimeFormatter.ofLocalizedTime(FormatStyle.LONG)); - System.out.println(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)); - System.out.println(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT)); - System.out.println(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.MEDIUM)); - System.out.println(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.LONG)); - System.out.println(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL)); - } - } - """ - ) - ); - } - - @Test - void migrateJodaDuration() { - // language=java - rewriteRun( - java( - """ - import org.joda.time.Duration; - - class A { - public void foo() { - System.out.println(Duration.standardDays(1L)); - System.out.println(Duration.standardHours(1L)); - System.out.println(Duration.standardMinutes(1L)); - System.out.println(Duration.standardSeconds(1L)); - System.out.println(Duration.millis(1000L)); - System.out.println(new Duration(1000L)); - System.out.println(new Duration(1000L, 2000L)); - System.out.println(new Duration(1000L).getStandardDays()); - System.out.println(new Duration(1000L).getStandardHours()); - System.out.println(new Duration(1000L).getStandardMinutes()); - System.out.println(new Duration(1000L).getStandardSeconds()); - System.out.println(new Duration(1000L).toDuration()); - System.out.println(new Duration(1000L).withMillis(2000L)); - System.out.println(new Duration(1000L).withDurationAdded(550L, 2)); - System.out.println(new Duration(1000L).withDurationAdded(new Duration(550L), 2)); - System.out.println(new Duration(1000L).plus(550L)); - System.out.println(new Duration(1000L).plus(new Duration(550L))); - System.out.println(new Duration(1000L).minus(550L)); - System.out.println(new Duration(1000L).minus(new Duration(550L))); - System.out.println(new Duration(1000L).multipliedBy(2)); - System.out.println(new Duration(1000L).dividedBy(2)); - System.out.println(new Duration(1000L).negated()); - System.out.println(new Duration(1000L).abs()); - } - } - """, - """ - import java.time.Duration; - import java.time.Instant; - - class A { - public void foo() { - System.out.println(Duration.ofDays(1L)); - System.out.println(Duration.ofHours(1L)); - System.out.println(Duration.ofMinutes(1L)); - System.out.println(Duration.ofSeconds(1L)); - System.out.println(Duration.ofMillis(1000L)); - System.out.println(Duration.ofMillis(1000L)); - System.out.println(Duration.between(Instant.ofEpochMilli(1000L), Instant.ofEpochMilli(2000L))); - System.out.println(Duration.ofMillis(1000L).toDays()); - System.out.println(Duration.ofMillis(1000L).toHours()); - System.out.println(Duration.ofMillis(1000L).toMinutes()); - System.out.println(Duration.ofMillis(1000L).getSeconds()); - System.out.println(Duration.ofMillis(1000L)); - System.out.println(Duration.ofMillis(2000L)); - System.out.println(Duration.ofMillis(1000L).plusMillis(550L * 2)); - System.out.println(Duration.ofMillis(1000L).plus(Duration.ofMillis(550L).multipliedBy(2))); - System.out.println(Duration.ofMillis(1000L).plusMillis(550L)); - System.out.println(Duration.ofMillis(1000L).plus(Duration.ofMillis(550L))); - System.out.println(Duration.ofMillis(1000L).minusMillis(550L)); - System.out.println(Duration.ofMillis(1000L).minus(Duration.ofMillis(550L))); - System.out.println(Duration.ofMillis(1000L).multipliedBy(2)); - System.out.println(Duration.ofMillis(1000L).dividedBy(2)); - System.out.println(Duration.ofMillis(1000L).negated()); - System.out.println(Duration.ofMillis(1000L).abs()); - } - } - """ - ) - ); - } - - @Test - void migrateAbstractInstant() { - // language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.Duration; - import org.joda.time.Instant; - import org.joda.time.format.DateTimeFormat; - - class A { - public void foo() { - new DateTime().equals(DateTime.now()); - new DateTime().getZone(); - new DateTime().isAfter(1234567890L); - new Instant().isAfter(1234567890L); - new DateTime().isAfter(DateTime.now().minusDays(1)); - new Instant().isAfter(Instant.now().minus(Duration.standardDays(1))); - new DateTime().isBefore(1234567890L); - new Instant().isBefore(1234567890L); - new DateTime().isBefore(DateTime.now().plusDays(1)); - new Instant().isBefore(Instant.now().plus(Duration.standardDays(1))); - new DateTime().isBeforeNow(); - new DateTime().isEqual(1234567890L); - new DateTime().isEqual(DateTime.now().plusDays(1)); - new DateTime().toDate(); - new DateTime().toInstant(); - new DateTime().toString(); - new DateTime().toString(DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss")); - } - } - """, - """ - import java.time.Duration; - import java.time.Instant; - import java.time.ZoneId; - import java.time.ZonedDateTime; - import java.time.format.DateTimeFormatter; - import java.util.Date; - - class A { - public void foo() { - ZonedDateTime.now().equals(ZonedDateTime.now()); - ZonedDateTime.now().getZone(); - ZonedDateTime.now().isAfter(Instant.ofEpochMilli(1234567890L).atZone(ZoneId.systemDefault())); - Instant.now().isAfter(Instant.ofEpochMilli(1234567890L)); - ZonedDateTime.now().isAfter(ZonedDateTime.now().minusDays(1)); - Instant.now().isAfter(Instant.now().minus(Duration.ofDays(1))); - ZonedDateTime.now().isBefore(Instant.ofEpochMilli(1234567890L).atZone(ZoneId.systemDefault())); - Instant.now().isBefore(Instant.ofEpochMilli(1234567890L)); - ZonedDateTime.now().isBefore(ZonedDateTime.now().plusDays(1)); - Instant.now().isBefore(Instant.now().plus(Duration.ofDays(1))); - ZonedDateTime.now().isBefore(ZonedDateTime.now()); - ZonedDateTime.now().isEqual(Instant.ofEpochMilli(1234567890L).atZone(ZoneId.systemDefault())); - ZonedDateTime.now().isEqual(ZonedDateTime.now().plusDays(1)); - Date.from(ZonedDateTime.now().toInstant()); - ZonedDateTime.now().toInstant(); - ZonedDateTime.now().toString(); - ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")); - } - } - """ - ) - ); - } - - @Test - void migrateAbstractDateTime() { - // language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - - class A { - public void foo() { - new DateTime().getDayOfMonth(); - new DateTime().getDayOfWeek(); - new DateTime().getHourOfDay(); - new DateTime().getMillisOfSecond(); - new DateTime().getMinuteOfDay(); - new DateTime().getMinuteOfHour(); - new DateTime().getMonthOfYear(); - new DateTime().getSecondOfDay(); - new DateTime().getSecondOfMinute(); - new DateTime().getWeekOfWeekyear(); - new DateTime().toString(); - } - } - """, - """ - import java.time.ZonedDateTime; - import java.time.temporal.ChronoField; - - class A { - public void foo() { - ZonedDateTime.now().getDayOfMonth(); - ZonedDateTime.now().getDayOfWeek().getValue(); - ZonedDateTime.now().getHour(); - ZonedDateTime.now().get(ChronoField.MILLI_OF_SECOND); - ZonedDateTime.now().get(ChronoField.MINUTE_OF_DAY); - ZonedDateTime.now().getMinute(); - ZonedDateTime.now().getMonthValue(); - ZonedDateTime.now().get(ChronoField.SECOND_OF_DAY); - ZonedDateTime.now().getSecond(); - ZonedDateTime.now().get(ChronoField.ALIGNED_WEEK_OF_YEAR); - ZonedDateTime.now().toString(); - } - } - """ - ) - ); - } - - @Test - void migrateDateTimeFormatter() { - // language=java - rewriteRun( - java( - """ - import org.joda.time.format.DateTimeFormat; - import org.joda.time.DateTime; - import org.joda.time.DateTimeZone; - - class A { - public void foo() { - DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss").parseDateTime("2024-10-25T15:45:00"); - DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss").parseMillis("2024-10-25T15:45:00"); - DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss").print(1234567890L); - DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss").print(new DateTime()); - DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(DateTimeZone.UTC); - DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZoneUTC(); - } - } - """, - """ - import java.time.Instant; - import java.time.ZoneId; - import java.time.ZoneOffset; - import java.time.ZonedDateTime; - import java.time.format.DateTimeFormatter; - - class A { - public void foo() { - ZonedDateTime.parse("2024-10-25T15:45:00", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")); - ZonedDateTime.parse("2024-10-25T15:45:00", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")).toInstant().toEpochMilli(); - ZonedDateTime.ofInstant(Instant.ofEpochMilli(1234567890L), ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")); - ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")); - DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(ZoneOffset.UTC); - DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(ZoneOffset.UTC); - } - } - """ - ) - ); - } - - @Test - void migrateInstant() { - // language=java - rewriteRun( - java( - """ - import org.joda.time.Instant; - import org.joda.time.Duration; - - class A { - public void foo() { - System.out.println(new Instant()); - System.out.println(Instant.now().getMillis()); - System.out.println(Instant.now().minus(Duration.standardDays(1L))); - System.out.println(Instant.ofEpochMilli(1234567890L)); - System.out.println(Instant.parse("2024-10-25T15:45:00")); - System.out.println(Instant.now().plus(Duration.standardDays(1L))); - } - } - """, - """ - import java.time.Duration; - import java.time.Instant; - - class A { - public void foo() { - System.out.println(Instant.now()); - System.out.println(Instant.now().toEpochMilli()); - System.out.println(Instant.now().minus(Duration.ofDays(1L))); - System.out.println(Instant.ofEpochMilli(1234567890L)); - System.out.println(Instant.parse("2024-10-25T15:45:00")); - System.out.println(Instant.now().plus(Duration.ofDays(1L))); - } - } - """ - ) - ); - } - - @Test - void migrateClassesWithFqn() { - // language=java - rewriteRun( - java( - """ - class A { - public void foo() { - System.out.println(org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); - } - } - """, - """ - import java.time.format.DateTimeFormatter; - - class A { - public void foo() { - System.out.println(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); - } - } - """ - ) - ); - } - - @Test - void migrateJodaTypeExpressionReferencingNonJodaTypeVar() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - - class A { - public void foo() { - long millis = DateTime.now().getMillis(); - System.out.println(millis); - } - } - """, - """ - import java.time.ZonedDateTime; - - class A { - public void foo() { - long millis = ZonedDateTime.now().toInstant().toEpochMilli(); - System.out.println(millis); - } - } - """ - ) - ); - } - - @Test - void dontChangeMethodsWithUnhandledArguments() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.format.DateTimeFormat; - - class A { - public void foo() { - // DateTimeFormat.forStyle is unhandled so parent method should not be changed - System.out.println(DateTime.parse("2024-09-30T23:03:00.000Z", DateTimeFormat.forStyle("SS"))); - } - } - """ - ) - ); - } - - @Test - void unhandledCases() { - //language=java - rewriteRun( - java( - """ - import org.joda.time.PeriodType; - - class A { - public void foo() { - PeriodType.standard(); - } - } - """ - ) - ); - } - - @Test - void methodInvocationWithStaticImport() { - //language=java - rewriteRun( - java( - """ - import static org.joda.time.DateTime.now; - - class A { - public void foo() { - now(); - } - } - """, - """ - import java.time.ZonedDateTime; - - class A { - public void foo() { - ZonedDateTime.now(); - } - } - """ - ) - ); - } - - @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.PeriodType; - - class A { - public void foo(PeriodType periodType) { - periodType = PeriodType.days(); - } - } - """ - ) - ); - } - - @Test - void migrateInterval() { - // language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.Duration; - import org.joda.time.Interval; - import org.joda.time.DateTimeZone; - - class A { - public void foo() { - System.out.println(new Interval(50, 100)); - System.out.println(new Interval(50, 100, DateTimeZone.UTC)); - System.out.println(new Interval(DateTime.now(), DateTime.now().plusDays(1))); - System.out.println(new Interval(DateTime.now(), Duration.standardDays(1))); - } - } - """, - """ - import org.threeten.extra.Interval; - - import java.time.Duration; - import java.time.Instant; - import java.time.ZonedDateTime; - - class A { - public void foo() { - System.out.println(Interval.of(Instant.ofEpochMilli(50), Instant.ofEpochMilli(100))); - System.out.println(Interval.of(Instant.ofEpochMilli(50), Instant.ofEpochMilli(100))); - System.out.println(Interval.of(ZonedDateTime.now().toInstant(), ZonedDateTime.now().plusDays(1).toInstant())); - System.out.println(Interval.of(ZonedDateTime.now().toInstant(), Duration.ofDays(1))); - } - } - """ - ) - ); - } - - @Test - void migrateAbstractInterval() { - // language=java - rewriteRun( - java( - """ - import org.joda.time.DateTime; - import org.joda.time.Interval; - - class A { - public void foo() { - new Interval(50, 100).getStart(); - new Interval(50, 100).getEnd(); - new Interval(50, 100).toDuration(); - new Interval(50, 100).toDurationMillis(); - new Interval(50, 100).contains(75); - } - } - """, - """ - import org.threeten.extra.Interval; - - import java.time.Instant; - import java.time.ZoneId; - - class A { - public void foo() { - Interval.of(Instant.ofEpochMilli(50), Instant.ofEpochMilli(100)).getStart().atZone(ZoneId.systemDefault()); - Interval.of(Instant.ofEpochMilli(50), Instant.ofEpochMilli(100)).getEnd().atZone(ZoneId.systemDefault()); - Interval.of(Instant.ofEpochMilli(50), Instant.ofEpochMilli(100)).toDuration(); - Interval.of(Instant.ofEpochMilli(50), Instant.ofEpochMilli(100)).toDuration().toMillis(); - Interval.of(Instant.ofEpochMilli(50), Instant.ofEpochMilli(100)).contains(Instant.ofEpochMilli(75)); - } - } - """ - ) - ); - } - - @Test - void migrateBaseDuration() { - // language=java - rewriteRun( - java( - """ - import org.joda.time.Duration; - - class A { - public void foo() { - Duration d = new Duration(100); - d.getMillis(); - } - } - """, - """ - import java.time.Duration; - - class A { - public void foo() { - Duration d = Duration.ofMillis(100); - d.toMillis(); - } - } - """ - ) - ); - } - - @Test - void migrateBaseInterval() { - // language=java - rewriteRun( - java( - """ - import org.joda.time.Interval; - - class A { - public void foo() { - Interval i = new Interval(50, 100); - long s = i.getStartMillis(); - long e = i.getEndMillis(); - } - } - """, - """ - import org.threeten.extra.Interval; - - import java.time.Instant; - - class A { - public void foo() { - Interval i = Interval.of(Instant.ofEpochMilli(50), Instant.ofEpochMilli(100)); - long s = i.getStart().toEpochMilli(); - long e = i.getEnd().toEpochMilli(); - } - } - """ - ) - ); - } -} diff --git a/src/test/java/org/openrewrite/java/migrate/joda/NoJodaTimeTest.java b/src/test/java/org/openrewrite/java/migrate/joda/NoJodaTimeTest.java deleted file mode 100644 index adfdd5123f..0000000000 --- a/src/test/java/org/openrewrite/java/migrate/joda/NoJodaTimeTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * 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.migrate.joda; - -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.*; -import static org.openrewrite.maven.Assertions.pomXml; - -class NoJodaTimeTest implements RewriteTest { - - @Override - public void defaults(RecipeSpec spec) { - spec - .recipeFromResource("/META-INF/rewrite/no-joda-time.yml", "org.openrewrite.java.migrate.joda.NoJodaTime") - .parser(JavaParser.fromJavaVersion().classpath("joda-time", "threeten-extra")); - } - - @DocumentExample - @Test - void migrateJodaTime() { - rewriteRun( - mavenProject("foo", - srcMainJava( - // language=java - java( - """ - import org.joda.time.DateTime; - import org.joda.time.Interval; - - class A { - void foo() { - DateTime dt = new DateTime(); - DateTime dt1 = new DateTime().plusDays(1); - Interval i = new Interval(dt, dt1); - System.out.println(i.toDuration()); - } - } - """, - """ - import org.threeten.extra.Interval; - - import java.time.ZonedDateTime; - - class A { - void foo() { - ZonedDateTime dt = ZonedDateTime.now(); - ZonedDateTime dt1 = ZonedDateTime.now().plusDays(1); - Interval i = Interval.of(dt.toInstant(), dt1.toInstant()); - System.out.println(i.toDuration()); - } - } - """ - ), - //language=xml - pomXml( - """ - - 4.0.0 - com.example.foobar - foobar-core - 1.0.0 - - - joda-time - joda-time - 2.12.3 - - - - """, - """ - - 4.0.0 - com.example.foobar - foobar-core - 1.0.0 - - - joda-time - joda-time - 2.12.3 - - - org.threeten - threeten-extra - 1.8.0 - - - - """ - ) - ) - ) - ); - } -}