Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

org.openrewrite.java.cleanup.RenamePrivateFieldsToCamelCase does not recognize @Data lombok annotation #8

Open
blipper opened this issue Apr 15, 2023 · 10 comments
Labels
bug Something isn't working good first issue Good for newcomers

Comments

@blipper
Copy link
Contributor

blipper commented Apr 15, 2023

org.openrewrite.java.cleanup.RenamePrivateFieldsToCamelCase only checks if there is a private field. It does not recognize @DaTa or any other lombok annotation so renaming the field will introducing a breaking change. To preserve compatibility it should ignore private fields if the class is annotated with @Data/@Getter/@Setter

@timtebeek
Copy link
Contributor

Hi @blipper ! While we do not yet support lombok, we can and indeed should at least not make any changes to private fields when lombok annotations are present. Thanks for the suggestion!

I think it should be fairly easy to detect such annotations to begin with; either on the field directly, or on the surrounding class. The first step is likely a unit test in RenamePrivateFieldsToCamelCaseTest.java that replicates the issue, before we add detection and skip logic in RenamePrivateFieldsToCamelCase.java.

@timtebeek timtebeek added the bug Something isn't working label Apr 15, 2023
@timtebeek timtebeek transferred this issue from openrewrite/rewrite May 1, 2023
@timtebeek timtebeek moved this to Backlog in OpenRewrite May 1, 2023
@rpau rpau added this to the Good first experience with static code analysis recipes milestone May 30, 2023
@timtebeek timtebeek removed this from the Good first experience with static code analysis recipes milestone Nov 30, 2023
@timtebeek
Copy link
Contributor

@gwydionmv added a very similar change in

That could be replicated here to make RenamePrivateFieldsToCamelCase skip classes or fields with Lombok annotations.

@timtebeek
Copy link
Contributor

As part of that change we'd then likely want to do the same for ExplicitInitializationVisitor

Iterator<Cursor> clz = getCursor().getPathAsCursors(c -> c.getValue() instanceof J.ClassDeclaration);
if (clz.hasNext() && service(AnnotationService.class).matches(clz.next(), LOMBOK_VALUE)) {
return v;
}

@gwydionmv
Copy link
Contributor

gwydionmv commented Jan 18, 2024

@timtebeek after thinking about this, it's not exactly the same case, right? Lombok makes some "unsued" variables being used in the getters/setters, so removing them would be wrong. But if a recipe is applied and a variable "HasToChange" is changed to "hasToChange", it doesn't matter if it had lombok annotation or not, it was wrong 😅

@blipper
Copy link
Contributor Author

blipper commented Jan 18, 2024

Ultimately what think is needed for all of these annotation processors is a mechanism where rewrite has access to the paired byte code generated at compilation time. AST analysis will never be enough with annotation processors.

@blipper
Copy link
Contributor Author

blipper commented Jan 18, 2024

Or a at a minimum if you want to keep pure AST analysis you need to pair with the delomboked source

@timtebeek
Copy link
Contributor

Thanks for helping think this one through! The reason I'd want to skip lombok annotated classes and fields is that this recipe also changes snake case to camel case, as seen in this test case

private String D_TYPE_CONNECT = "";
}
""",
"""
class Test {
private String dTypeConnect = "";

I'm not a 100% sure what getters lombok would generate before and after the rename, but I think that'd be getD_TYPE_CONNECT(), so best skipped.

@timtebeek timtebeek added the good first issue Good for newcomers label Jan 18, 2024
@gwydionmv
Copy link
Contributor

yes, yes, you're right, that's what Lombok generates for that field, .getD_TYPE_CONNECT(). And that's what my point was, if that variable name is wrong, then it's ok that the recipe breaks the code, isn't it? It won't be as automatic as other recipes, but I don't find it a bad thing that after running the recipe the dev has to replace the old getter with getDTypeConnect()

@timtebeek
Copy link
Contributor

I understand where you're coming from in that if you want to thoroughly clean up the code in a single repository, that it's then perhaps acceptable to have to put some effort as well. However, we strongly belief in keeping to our do no harm convention, where we only make a code change when we believe it safe to do so.

Consider for example that you're not looking at a single project but dozens or even hundreds; and then not running a single recipe, but also dozens or hundreds. In those cases you'd much rather have each of those recipes not make a change when there's potential to break code, as there would be a lot of code to check afterwards. Or consider the case where you run the recipe on a library, that may then subtly change the exposed getter, which you might only notice in consumers.

Given the above I think it's best to make all the code changes we know are safe, and back off from making code changes when there might be unhandled side effects such as in the case of Lombok annotated fields. That's also why we for instance don't run our "Convert @lombok.Value class to Record" recipe by default. As much as we think it might improve code, there's also potential for negative effects in downstream consumers of libraries, so we leave it up to the user to consider running that by itself as desired.

@blipper
Copy link
Contributor Author

blipper commented Jan 19, 2024

Working at Amazon and previously worked at Google which both operate at scale you need to minimize false positives so +1.

That being said with Lombok the private fields are similar to records is that they become a public API/source of truth so arguably they aren't private at all anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers
Projects
Status: Backlog
Development

No branches or pull requests

4 participants