diff --git a/src/main/java/org/openrewrite/java/migrate/util/UseEnumSetOf.java b/src/main/java/org/openrewrite/java/migrate/util/UseEnumSetOf.java index 61b169b8a1..d67df418cb 100644 --- a/src/main/java/org/openrewrite/java/migrate/util/UseEnumSetOf.java +++ b/src/main/java/org/openrewrite/java/migrate/util/UseEnumSetOf.java @@ -17,8 +17,8 @@ import org.jspecify.annotations.Nullable; import org.openrewrite.*; -import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.JavaVisitor; import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.search.UsesJavaVersion; import org.openrewrite.java.search.UsesMethod; @@ -33,6 +33,7 @@ public class UseEnumSetOf extends Recipe { private static final MethodMatcher SET_OF = new MethodMatcher("java.util.Set of(..)", true); + private static final String METHOD_TYPE = "java.util.EnumSet"; @Override public String getDisplayName() { @@ -52,59 +53,72 @@ public Duration getEstimatedEffortPerOccurrence() { @Override public TreeVisitor getVisitor() { return Preconditions.check(Preconditions.and(new UsesJavaVersion<>(9), - new UsesMethod<>(SET_OF)), new JavaIsoVisitor() { - @Override - public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { - J.MethodInvocation m = super.visitMethodInvocation(method, ctx); + new UsesMethod<>(SET_OF)), new UseEnumSetOfVisitor()); + } - if (SET_OF.matches(method) && method.getType() instanceof JavaType.Parameterized && - !TypeUtils.isOfClassType(method.getType(), "java.util.EnumSet")) { - Cursor parent = getCursor().dropParentUntil(is -> is instanceof J.Assignment || is instanceof J.VariableDeclarations || is instanceof J.Block); - if (!(parent.getValue() instanceof J.Block)) { - JavaType type = parent.getValue() instanceof J.Assignment ? - ((J.Assignment) parent.getValue()).getType() : ((J.VariableDeclarations) parent.getValue()).getVariables().get(0).getType(); - if (isAssignmentSetOfEnum(type)) { - maybeAddImport("java.util.EnumSet"); + private static class UseEnumSetOfVisitor extends JavaVisitor { + @Override + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation methodInvocation, ExecutionContext ctx) { + J.MethodInvocation mi = (J.MethodInvocation) super.visitMethodInvocation(methodInvocation, ctx); - List args = m.getArguments(); - if (isArrayParameter(args)) { - return m; - } + if (SET_OF.matches(mi) && + mi.getType() instanceof JavaType.Parameterized && + !TypeUtils.isOfClassType(mi.getType(), METHOD_TYPE)) { + Cursor parent = getCursor().dropParentUntil(is -> is instanceof J.Assignment || is instanceof J.VariableDeclarations || is instanceof J.Block); + if (!(parent.getValue() instanceof J.Block)) { + JavaType type = parent.getValue() instanceof J.Assignment ? + ((J.Assignment) parent.getValue()).getType() : ((J.VariableDeclarations) parent.getValue()).getVariables().get(0).getType(); + if (isAssignmentSetOfEnum(type)) { + maybeAddImport(METHOD_TYPE); - StringJoiner setOf = new StringJoiner(", ", "EnumSet.of(", ")"); - args.forEach(o -> setOf.add("#{any()}")); + List args = mi.getArguments(); + if (isArrayParameter(args)) { + return mi; + } - return JavaTemplate.builder(setOf.toString()) + if (args.get(0) instanceof J.Empty) { + JavaType firstTypeParameter = ((JavaType.Parameterized) type).getTypeParameters().get(0); + JavaType.ShallowClass shallowClass = JavaType.ShallowClass.build(firstTypeParameter.toString()); + return JavaTemplate.builder("EnumSet.noneOf(" + shallowClass.getClassName() + ".class)") .contextSensitive() - .imports("java.util.EnumSet") + .imports(METHOD_TYPE) .build() - .apply(updateCursor(m), m.getCoordinates().replace(), args.toArray()); + .apply(updateCursor(mi), mi.getCoordinates().replace()); } + + StringJoiner setOf = new StringJoiner(", ", "EnumSet.of(", ")"); + args.forEach(o -> setOf.add("#{any()}")); + return JavaTemplate.builder(setOf.toString()) + .contextSensitive() + .imports(METHOD_TYPE) + .build() + .apply(updateCursor(mi), mi.getCoordinates().replace(), args.toArray()); } } - return m; } + return mi; + } - private boolean isAssignmentSetOfEnum(@Nullable JavaType type) { - if (type instanceof JavaType.Parameterized) { - JavaType.Parameterized parameterized = (JavaType.Parameterized) type; - if (TypeUtils.isOfClassType(parameterized.getType(), "java.util.Set")) { - return ((JavaType.Parameterized) type).getTypeParameters().stream() - .filter(org.openrewrite.java.tree.JavaType.Class.class::isInstance) - .map(org.openrewrite.java.tree.JavaType.Class.class::cast) - .anyMatch(o -> o.getKind() == JavaType.FullyQualified.Kind.Enum); - } + private boolean isAssignmentSetOfEnum(@Nullable JavaType type) { + if (type instanceof JavaType.Parameterized) { + JavaType.Parameterized parameterized = (JavaType.Parameterized) type; + if (TypeUtils.isOfClassType(parameterized.getType(), "java.util.Set")) { + return ((JavaType.Parameterized) type).getTypeParameters().stream() + .filter(org.openrewrite.java.tree.JavaType.Class.class::isInstance) + .map(org.openrewrite.java.tree.JavaType.Class.class::cast) + .anyMatch(o -> o.getKind() == JavaType.FullyQualified.Kind.Enum); } - return false; } + return false; + } - private boolean isArrayParameter(final List args) { - if (args.size() != 1) { - return false; - } - JavaType type = args.get(0).getType(); - return TypeUtils.asArray(type) != null; + private boolean isArrayParameter(final List args) { + if (args.size() != 1) { + return false; } - }); + JavaType type = args.get(0).getType(); + return TypeUtils.asArray(type) != null; + } } + } diff --git a/src/test/java/org/openrewrite/java/migrate/util/UseEnumSetOfTest.java b/src/test/java/org/openrewrite/java/migrate/util/UseEnumSetOfTest.java index 38ea2d0594..b37b217ebd 100644 --- a/src/test/java/org/openrewrite/java/migrate/util/UseEnumSetOfTest.java +++ b/src/test/java/org/openrewrite/java/migrate/util/UseEnumSetOfTest.java @@ -39,7 +39,7 @@ void changeDeclaration() { java( """ import java.util.Set; - + class Test { public enum Color { RED, GREEN, BLUE @@ -52,7 +52,7 @@ public void method() { """ import java.util.EnumSet; import java.util.Set; - + class Test { public enum Color { RED, GREEN, BLUE @@ -76,7 +76,7 @@ void changeAssignment() { java( """ import java.util.Set; - + class Test { public enum Color { RED, GREEN, BLUE @@ -90,7 +90,7 @@ public void method() { """ import java.util.EnumSet; import java.util.Set; - + class Test { public enum Color { RED, GREEN, BLUE @@ -116,7 +116,7 @@ void dontChangeVarargs() { java( """ import java.util.Set; - + class Test { public enum Color { RED, GREEN, BLUE @@ -141,7 +141,7 @@ void dontChangeArray() { java( """ import java.util.Set; - + class Test { public enum Color { RED, GREEN, BLUE @@ -157,4 +157,39 @@ public void method() { ) ); } + + @Test + @Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/490") + void dontHaveArgs() { + //language=java + rewriteRun( + version( + java( + """ + import java.util.Set; + import java.util.concurrent.TimeUnit; + class Test { + + public void method() { + Set warm = Set.of(); + } + } + """, + """ + import java.util.EnumSet; + import java.util.Set; + import java.util.concurrent.TimeUnit; + + class Test { + + public void method() { + Set warm = EnumSet.noneOf(TimeUnit.class); + } + } + """ + ), + 9 + ) + ); + } }