2020import org .openrewrite .Recipe ;
2121import org .openrewrite .TreeVisitor ;
2222import org .openrewrite .java .JavaIsoVisitor ;
23+ import org .openrewrite .java .MethodMatcher ;
24+ import org .openrewrite .java .search .DeclaresMethod ;
2325import org .openrewrite .java .search .UsesJavaVersion ;
2426import org .openrewrite .java .tree .J ;
2527import org .openrewrite .java .tree .JavaType ;
3335import static java .util .Collections .emptyList ;
3436
3537public class MigrateMainMethodToInstanceMain extends Recipe {
38+
39+ private static final MethodMatcher MAIN_METHOD_MATCHER = new MethodMatcher ("*..* main(String[])" , false );
40+
3641 @ Override
3742 public String getDisplayName () {
3843 return "Migrate `public static void main(String[] args)` to instance `void main()`" ;
@@ -45,19 +50,23 @@ public String getDescription() {
4550
4651 @ Override
4752 public TreeVisitor <?, ExecutionContext > getVisitor () {
48- return Preconditions .check (new UsesJavaVersion <>(25 ), new JavaIsoVisitor <ExecutionContext >() {
53+ TreeVisitor <?, ExecutionContext > preconditions = Preconditions .and (
54+ new UsesJavaVersion <>(25 ),
55+ new DeclaresMethod <>(MAIN_METHOD_MATCHER )
56+ );
57+ return Preconditions .check (preconditions , new JavaIsoVisitor <ExecutionContext >() {
4958 @ Override
5059 public J .MethodDeclaration visitMethodDeclaration (J .MethodDeclaration method , ExecutionContext ctx ) {
60+ J .ClassDeclaration enclosingClass = getCursor ().firstEnclosing (J .ClassDeclaration .class );
5161 J .MethodDeclaration md = super .visitMethodDeclaration (method , ctx );
5262
5363 // Check if this is a main method: public static void main(String[] args)
54- if (!"main" .equals (md .getSimpleName ()) ||
64+ if (enclosingClass == null ||
65+ !MAIN_METHOD_MATCHER .matches (md , enclosingClass ) ||
5566 md .getReturnTypeExpression () == null ||
5667 md .getReturnTypeExpression ().getType () != JavaType .Primitive .Void ||
5768 !md .hasModifier (J .Modifier .Type .Public ) ||
5869 !md .hasModifier (J .Modifier .Type .Static ) ||
59- md .getParameters ().size () != 1 ||
60- !(md .getParameters ().get (0 ) instanceof J .VariableDeclarations ) ||
6170 md .getBody () == null ) {
6271 return md ;
6372 }
@@ -69,24 +78,10 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, Ex
6978 return md ;
7079 }
7180
72- // Get the enclosing class
73- J .ClassDeclaration enclosingClass = getCursor ().firstEnclosing (J .ClassDeclaration .class );
74- if (enclosingClass == null ) {
75- return md ;
76- }
77-
78- // Check 1: Do not migrate if class has @SpringBootApplication annotation
79- if (hasSpringBootApplicationAnnotation (enclosingClass )) {
80- return md ;
81- }
82-
83- // Check 2: Do not migrate if class doesn't have a no-arg constructor
84- if (!hasNoArgConstructor (enclosingClass )) {
85- return md ;
86- }
87-
88- // Check 3: Do not migrate if main method is used as a method reference
89- if (isMainMethodReferenced (md )) {
81+ // Do not migrate in any of these cases
82+ if (hasSpringBootApplicationAnnotation (enclosingClass ) ||
83+ !hasNoArgConstructor (enclosingClass ) ||
84+ isMainMethodReferenced (md )) {
9085 return md ;
9186 }
9287
0 commit comments