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 9faf8aa386..ab1fa29d33 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValueToRecord.java @@ -254,6 +254,32 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu ); } + @Override + public J.MemberReference visitMemberReference(J.MemberReference memberRef, ExecutionContext ctx) { + J.MemberReference memberReference = super.visitMemberReference(memberRef, ctx); + + Expression containing = memberReference.getContaining(); + 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)) { + + JavaType.Method methodType = memberReference.getMethodType(); + if (methodType != null) { + methodType = methodType.withName(newSimpleName); + } + return memberReference + .withReference(reference.withSimpleName(newSimpleName)) + .withMethodType(methodType); + } + } + 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 d97ab2067f..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,6 +26,7 @@ import static org.openrewrite.java.Assertions.*; +@SuppressWarnings({"ClassCanBeRecord", "LombokGetterMayBeUsed", "NullableProblems", "TypeParameterExplicitlyExtendsObject"}) class LombokValueToRecordTest implements RewriteTest { @Override @@ -46,8 +47,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 +141,6 @@ public String toString() { void onlyRemoveAnnotationFromRecords() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; @@ -185,7 +183,6 @@ public class B { void innerRecordsNotStatic() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; @@ -218,7 +215,6 @@ record B( void interfaceIsImplementedThatDoesNotDefineFieldGetter() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; @@ -248,13 +244,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 +262,7 @@ public class A implements Serializable { package example; import lombok.Builder; + import java.io.Serializable; @Builder public record A( @@ -274,7 +271,46 @@ public record A( """ ) ); + } + + @Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/449") + @Test + void methodReferences() { + //language=java + rewriteRun( + java( + """ + import lombok.Value; + import java.util.function.Supplier; + + @Value + class A { + String test; + } + + class Using { + Supplier usingMethodReference() { + A a = new A("foo"); + return a::getTest; + } + } + """, + """ + import java.util.function.Supplier; + record A( + String test) { + } + + class Using { + Supplier usingMethodReference() { + A a = new A("foo"); + return a::test; + } + } + """ + ) + ); } @Nested @@ -304,7 +340,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; @@ -433,7 +469,6 @@ public class A { void nonStaticInnerClass() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example; @@ -455,7 +490,6 @@ class B { void staticConstructor() { //language=java rewriteRun( - s -> s.typeValidationOptions(TypeValidation.none()), java( """ package example;