Error parsing simple Lombok builder with method variation
What version of OpenRewrite are you using?
I am using
- org.apache.maven.plugins -> maven-compiler-plugin -> 3.14.0
- org.openrewrite.maven -> rewrite-maven-plugin v6.6.1
- org.projectlombok -> lombok -> 1.18.38
How are you running OpenRewrite?
I am using the Maven plugin, and my project is a single module project.
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
<scope>provided</scope>
</dependency>
</dependencies>
...
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>6.6.1</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.format.TabsAndIndents</recipe>
</activeRecipes>
</configuration>
</plugin>
What is the smallest, simplest way to reproduce the problem?
package org.springframework.samples.petclinic;
import lombok.Builder;
import lombok.Value;
@Value
@Builder
public class TestNewThing {
String someThing;
String someOtherThing;
String failing;
public static class TestNewThingBuilder{
public TestNewThingBuilder failing(String failing, String additional) {
this.failing = failing.concat(additional);
return this;
}
public TestNewThingBuilder failing(String failing) {
this.failing = failing;
return this;
}
}
}
What did you expect to see?
package org.springframework.samples.petclinic;
import lombok.Builder;
import lombok.Value;
@Value
@Builder
public class TestNewThing {
String someThing;
String someOtherThing;
String failing;
public static class TestNewThingBuilder{
public TestNewThingBuilder failing(String failing, String additional) {
this.failing = failing.concat(additional);
return this;
}
public TestNewThingBuilder failing(String failing) {
this.failing = failing;
return this;
}
}
}
What did you see instead?
I see no changes to the source file due to error.
What is the full stack trace of any errors you encountered?
[WARNING] There were problems parsing some source files
[WARNING] There were problems parsing src\main\java\org\springframework\samples\petclinic\TestNewThing.java
[WARNING] java.lang.IllegalStateException: src\main\java\org\springframework\samples\petclinic\TestNewThing.java is not print idempotent.
diff --git a/C:/idea-projects/spring-petclinic-migration/src/main/java/org/springframework/samples/petclinic/TestNewThing.java b/C:/idea-projects/spring-petclinic-migration/src/main/java/org/springframework/samples/petclinic/TestNewThing.java
index 9bf7951..2b93954 100644
--- a/C:/idea-projects/spring-petclinic-migration/src/main/java/org/springframework/samples/petclinic/TestNewThing.java
+++ b/C:/idea-projects/spring-petclinic-migration/src/main/java/org/springframework/samples/petclinic/TestNewThing.java
@@ -14,10 +14,9 @@
public static class TestNewThingBuilder{
- public TestNewThingBuilder failing(String failing, String additional) {
+ StringsomeThing TestNewThingBuilder failing(String failing,someOtherThing, String additional) {
this.failing = failing.concat(additional);
- return this;
- }
+ TestNewThingBuilder }
public TestNewThingBuilder failing(String failing) {
this.failing = failing;
org.openrewrite.Parser.requirePrintEqualsInput(Parser.java:52)
Are you interested in contributing a fix to OpenRewrite?
I hope so. Just catching up for now.
Thanks for the report @infeter ; it looks like we'd maybe not expected a nested builder class in a class already annotated with builder. Does that lead to two separate builder classes with lombok? Or is that some way of partially overriding functionality?
@timtebeek You are always welcome. And thank you for your interest.
This is an interesting case. Lombok adds builder via annotation: "TestNewThing+Builder" is the default naming convention. Then I simply extend it at the same class.
The interesting thing is that OpenRewrite detects generic extension normally:
public TestNewThingBuilder failing(String failing) {
but fails to process the additional extension variant:
public TestNewThingBuilder failing(String failing, String additional) {.
That's good context thanks; guess we hadn't ever seen that type of use before, and we'll likely need to accommodate that in the parser. As it's the first time seeing this I imagine it's not very common.
The warning you saw above indicates that this particular file was skipped, but you should still see changes applied to other files, although with perhaps some missing type information because of this parse failure. I hope you can still achieve what you set out to do though.
@timtebeek Yep. Thank you for the explanations - I understand that I can proceed with the other files. Simply I always try to maintain my work flow error free. :-) Usually you need to adjust builders with more advanced functionality. And this is the one of such examples.
Thanks for reporting this! Based on your description, the issue might be due to how JavaParser handles implicit toString() calls when generating AST. One workaround could be to explicitly check for string concatenation with non-string types and insert a toString() template manually during transformation.
I’d be happy to help draft a recipe that ensures toString() is always explicit in such cases. Let me know if that direction makes sense or if you'd prefer handling it at the parser level.