From 038637c14a864af5132ed84cff924d73c277f5e0 Mon Sep 17 00:00:00 2001 From: Holger Partsch Date: Wed, 1 May 2024 15:42:33 +0200 Subject: [PATCH 1/9] try to rewrite method references --- .../migrate/lombok/LombokValueToRecord.java | 22 ++++++ .../lombok/LombokValueToRecordTest.java | 72 +++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java index 7e734eedab..9509385f9d 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java @@ -236,6 +236,28 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu ); } + @Override + public J.MemberReference visitMemberReference(J.MemberReference memberReference, ExecutionContext ctx) { + // when "memberReference" is "a::getTest" + // memberReference.getMethodType() == null + JavaType.Method methodType = memberReference.getMethodType(); + if(methodType == null) { + return memberReference; + } + + JavaType.FullyQualified declaringType = methodType.getDeclaringType(); + String methodName = methodType.getName(); + String classFqn = declaringType.getFullyQualifiedName(); + if(recordTypeToMembers.containsKey(classFqn) + && recordTypeToMembers.get(classFqn).contains(getterMethodNameToFluentMethodName(methodName)) + && methodName.startsWith(STANDARD_GETTER_PREFIX)) { + return memberReference.withMethodType(methodType.withName(getterMethodNameToFluentMethodName(methodName))); + } + + return memberReference; + } + + private boolean isMethodInvocationOnRecordTypeClassMember(J.MethodInvocation methodInvocation) { Expression expression = methodInvocation.getSelect(); if (!isClassExpression(expression)) { diff --git a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java index d0ebcd4e6e..7de608b393 100644 --- a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java @@ -24,6 +24,8 @@ import org.openrewrite.test.RewriteTest; import org.openrewrite.test.TypeValidation; +import java.util.function.Supplier; + import static org.openrewrite.java.Assertions.*; class LombokValueToRecordTest implements RewriteTest { @@ -243,6 +245,76 @@ public record A( ); } + public static class A { + String test; + + public String getTest() { + return test; + } + } + @Test + @Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/449") + void methodReferences() { + + var a = new A(); + + //language=java + rewriteRun( + s -> s.typeValidationOptions(TypeValidation.none()), + java( + """ + package example; + + import lombok.Value; + import java.util.function.Supplier; + + @Value + public class A { + String test; + + } + + class B { + + + public static String classMethod() { + return "foo"; + } + + } + + class Using { + + Supplier usingMethodReference() { + A a = new A("foo"); + return a::getTest; + } + + } + """, + """ + package example; + + import java.util.function.Supplier; + + public record A( + String test) { + } + + class Using { + + Supplier usingMethodReference() { + A a = new A("foo"); + return a::test; + } + + } + """ + ) + ); + + } + @Nested class Unchanged { @Test From a878f6dac810574270b4a772ac723af9a4363b4e Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Wed, 16 Jul 2025 15:33:50 +0200 Subject: [PATCH 2/9] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../java/migrate/lombok/LombokValueToRecord.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java index cabba05b45..f79e8ba716 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java @@ -266,9 +266,9 @@ public J.MemberReference visitMemberReference(J.MemberReference memberReference, JavaType.FullyQualified declaringType = methodType.getDeclaringType(); String methodName = methodType.getName(); String classFqn = declaringType.getFullyQualifiedName(); - if(recordTypeToMembers.containsKey(classFqn) - && recordTypeToMembers.get(classFqn).contains(getterMethodNameToFluentMethodName(methodName)) - && methodName.startsWith(STANDARD_GETTER_PREFIX)) { + if(recordTypeToMembers.containsKey(classFqn) && + recordTypeToMembers.get(classFqn).contains(getterMethodNameToFluentMethodName(methodName)) && + methodName.startsWith(STANDARD_GETTER_PREFIX)) { return memberReference.withMethodType(methodType.withName(getterMethodNameToFluentMethodName(methodName))); } From 5644f4b6c440d0ebf8ed6b07c70ecdb24c28ad14 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 18 Jul 2025 01:35:13 +0200 Subject: [PATCH 3/9] Alter implementation and polish tests --- .../migrate/lombok/LombokValueToRecord.java | 34 +++++++++------- .../lombok/LombokValueToRecordTest.java | 39 +++---------------- 2 files changed, 25 insertions(+), 48 deletions(-) diff --git a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java index 23dc6366c8..83986db536 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java @@ -255,27 +255,31 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu } @Override - public J.MemberReference visitMemberReference(J.MemberReference memberReference, ExecutionContext ctx) { - // when "memberReference" is "a::getTest" - // memberReference.getMethodType() == null - JavaType.Method methodType = memberReference.getMethodType(); - if(methodType == null) { - return memberReference; - } + public J.MemberReference visitMemberReference(J.MemberReference memberRef, ExecutionContext ctx) { + J.MemberReference memberReference = super.visitMemberReference(memberRef, ctx); + + // Handle method references like a::getTest + Expression containing = memberReference.getContaining(); + if (containing != null && containing.getType() instanceof JavaType.Class) { + JavaType.Class classType = (JavaType.Class) containing.getType(); + String classFqn = classType.getFullyQualifiedName(); + + J.Identifier reference = memberReference.getReference(); + String methodName = reference.getSimpleName(); + + if (recordTypeToMembers.containsKey(classFqn) && + methodName.startsWith(STANDARD_GETTER_PREFIX) && + recordTypeToMembers.get(classFqn).contains(getterMethodNameToFluentMethodName(methodName))) { - JavaType.FullyQualified declaringType = methodType.getDeclaringType(); - String methodName = methodType.getName(); - String classFqn = declaringType.getFullyQualifiedName(); - if(recordTypeToMembers.containsKey(classFqn) && - recordTypeToMembers.get(classFqn).contains(getterMethodNameToFluentMethodName(methodName)) && - methodName.startsWith(STANDARD_GETTER_PREFIX)) { - return memberReference.withMethodType(methodType.withName(getterMethodNameToFluentMethodName(methodName))); + return memberReference.withReference( + reference.withSimpleName(getterMethodNameToFluentMethodName(methodName)) + ); + } } return memberReference; } - private boolean isMethodInvocationOnRecordTypeClassMember(J.MethodInvocation methodInvocation) { Expression expression = methodInvocation.getSelect(); if (!isClassExpression(expression)) { diff --git a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java index b2389e43b2..48c7661690 100644 --- a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java @@ -24,8 +24,6 @@ import org.openrewrite.test.RewriteTest; import org.openrewrite.test.TypeValidation; -import java.util.function.Supplier; - import static org.openrewrite.java.Assertions.*; class LombokValueToRecordTest implements RewriteTest { @@ -279,74 +277,49 @@ public record A( } - public static class A { - String test; - - public String getTest() { - return test; - } - } @Test @Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/449") void methodReferences() { - - var a = new A(); - //language=java rewriteRun( s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; - + import lombok.Value; import java.util.function.Supplier; - + @Value public class A { String test; - } - - class B { - - - public static String classMethod() { - return "foo"; - } - - } - + class Using { - Supplier usingMethodReference() { A a = new A("foo"); return a::getTest; } - } """, """ package example; - + import java.util.function.Supplier; - + public record A( String test) { } - + class Using { - Supplier usingMethodReference() { A a = new A("foo"); return a::test; } - } """ ) ); - } @Nested From 5e78969a28a8ed9b8db5e3d4b9b0e92f9b93f101 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 18 Jul 2025 01:37:49 +0200 Subject: [PATCH 4/9] Stop ignoring type validation issues --- .../migrate/lombok/LombokValueToRecordTest.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java index 48c7661690..a6cc3a3847 100644 --- a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java @@ -46,8 +46,6 @@ public void defaults(RecipeSpec spec) { void convertOnlyValueAnnotatedClassWithoutDefaultValuesToRecord() { //language=java rewriteRun( - // TODO: find a way to please type validation so this workaround is not required anymore - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; @@ -142,7 +140,6 @@ public String toString() { void onlyRemoveAnnotationFromRecords() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; @@ -185,7 +182,6 @@ public class B { void innerRecordsNotStatic() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; @@ -218,7 +214,6 @@ record B( void interfaceIsImplementedThatDoesNotDefineFieldGetter() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; @@ -248,13 +243,13 @@ public record A( void plainLombokBuilder() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; import lombok.Value; import lombok.Builder; + import java.io.Serializable; @Value @Builder @@ -266,6 +261,7 @@ public class A implements Serializable { package example; import lombok.Builder; + import java.io.Serializable; @Builder public record A( @@ -282,7 +278,6 @@ public record A( void methodReferences() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; @@ -349,7 +344,7 @@ public A() { void classWithFieldAnnotations() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), + s -> s.typeValidationOptions(TypeValidation.all().identifiers(false)), java( """ import com.fasterxml.jackson.annotation.JsonProperty; @@ -478,7 +473,6 @@ public class A { void nonStaticInnerClass() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; @@ -500,7 +494,6 @@ class B { void staticConstructor() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; From 905a26f2977062c8d3a0d24f43b5a3be3d40814c Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 18 Jul 2025 01:40:30 +0200 Subject: [PATCH 5/9] Also update method type --- .../java/migrate/lombok/LombokValueToRecord.java | 15 +++++++++++---- .../migrate/lombok/LombokValueToRecordTest.java | 1 - 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java index 83986db536..ff3c56ca8b 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java @@ -267,13 +267,20 @@ public J.MemberReference visitMemberReference(J.MemberReference memberRef, Execu J.Identifier reference = memberReference.getReference(); String methodName = reference.getSimpleName(); + String newSimpleName = getterMethodNameToFluentMethodName(methodName); if (recordTypeToMembers.containsKey(classFqn) && methodName.startsWith(STANDARD_GETTER_PREFIX) && - recordTypeToMembers.get(classFqn).contains(getterMethodNameToFluentMethodName(methodName))) { + recordTypeToMembers.get(classFqn).contains(newSimpleName)) { - return memberReference.withReference( - reference.withSimpleName(getterMethodNameToFluentMethodName(methodName)) - ); + // Update the method type if present + JavaType.Method methodType = memberReference.getMethodType(); + if (methodType != null) { + methodType = methodType.withName(newSimpleName); + } + + return memberReference + .withReference(reference.withSimpleName(newSimpleName)) + .withMethodType(methodType); } } diff --git a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java index a6cc3a3847..159a661473 100644 --- a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java @@ -270,7 +270,6 @@ public record A( """ ) ); - } @Test From dd7b2747618e3041b609734f7f99dfe3c727796a Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 18 Jul 2025 10:22:25 +0200 Subject: [PATCH 6/9] Light polish --- .../java/migrate/lombok/LombokValueToRecord.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java index ff3c56ca8b..ab1fa29d33 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java @@ -258,32 +258,25 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu public J.MemberReference visitMemberReference(J.MemberReference memberRef, ExecutionContext ctx) { J.MemberReference memberReference = super.visitMemberReference(memberRef, ctx); - // Handle method references like a::getTest Expression containing = memberReference.getContaining(); - if (containing != null && containing.getType() instanceof JavaType.Class) { - JavaType.Class classType = (JavaType.Class) containing.getType(); - String classFqn = classType.getFullyQualifiedName(); - + if (containing.getType() instanceof JavaType.Class) { + String classFqn = ((JavaType.Class) containing.getType()).getFullyQualifiedName(); J.Identifier reference = memberReference.getReference(); String methodName = reference.getSimpleName(); - String newSimpleName = getterMethodNameToFluentMethodName(methodName); if (recordTypeToMembers.containsKey(classFqn) && methodName.startsWith(STANDARD_GETTER_PREFIX) && recordTypeToMembers.get(classFqn).contains(newSimpleName)) { - // Update the method type if present JavaType.Method methodType = memberReference.getMethodType(); if (methodType != null) { methodType = methodType.withName(newSimpleName); } - return memberReference .withReference(reference.withSimpleName(newSimpleName)) .withMethodType(methodType); } } - return memberReference; } From 93bb699dffc1aa8b15d5680b9059dfa6444351ce Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 18 Jul 2025 10:25:30 +0200 Subject: [PATCH 7/9] Minimize test --- .../java/migrate/lombok/LombokValueToRecordTest.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java index 159a661473..9b5314a388 100644 --- a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java @@ -26,6 +26,7 @@ import static org.openrewrite.java.Assertions.*; +@SuppressWarnings("NullableProblems") class LombokValueToRecordTest implements RewriteTest { @Override @@ -279,13 +280,11 @@ void methodReferences() { rewriteRun( java( """ - package example; - import lombok.Value; import java.util.function.Supplier; @Value - public class A { + class A { String test; } @@ -297,11 +296,9 @@ Supplier usingMethodReference() { } """, """ - package example; - import java.util.function.Supplier; - public record A( + record A( String test) { } @@ -316,6 +313,7 @@ Supplier usingMethodReference() { ); } + @SuppressWarnings({"TypeParameterExplicitlyExtendsObject", "ClassCanBeRecord", "LombokGetterMayBeUsed"}) @Nested class Unchanged { @Test From ff1a26b4a26ecb2e1a22ab45b572c5703914d843 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 18 Jul 2025 10:26:08 +0200 Subject: [PATCH 8/9] Fix annotation order --- .../java/migrate/lombok/LombokValueToRecordTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java index 9b5314a388..2d3997f586 100644 --- a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java @@ -273,8 +273,8 @@ public record A( ); } - @Test @Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/449") + @Test void methodReferences() { //language=java rewriteRun( From e4af006883186039a8892ebd31a58979e70d092a Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 18 Jul 2025 10:27:12 +0200 Subject: [PATCH 9/9] Pull up suppressions --- .../java/migrate/lombok/LombokValueToRecordTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java index 2d3997f586..0f0888df4c 100644 --- a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValueToRecordTest.java @@ -26,7 +26,7 @@ import static org.openrewrite.java.Assertions.*; -@SuppressWarnings("NullableProblems") +@SuppressWarnings({"ClassCanBeRecord", "LombokGetterMayBeUsed", "NullableProblems", "TypeParameterExplicitlyExtendsObject"}) class LombokValueToRecordTest implements RewriteTest { @Override @@ -313,7 +313,6 @@ Supplier usingMethodReference() { ); } - @SuppressWarnings({"TypeParameterExplicitlyExtendsObject", "ClassCanBeRecord", "LombokGetterMayBeUsed"}) @Nested class Unchanged { @Test