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

UseLambdaForFunctionalInterface should not convert when code uses a static field from enum constructor #413

Closed
jevanlingen opened this issue Dec 24, 2024 · 0 comments · Fixed by #415
Assignees
Labels
bug Something isn't working test provided

Comments

@jevanlingen
Copy link
Contributor

Problem

When running the UseLambdaForFunctionalInterface recipe, the code did no longer compile for a enum class. This enum class was a little special, as in the constructor an anonymous class was used with a reference to a static field. After conversion to a lambda, compilation error started to appear.

What is the smallest, simplest way to reproduce the problem?

@Test
void dontUseLambdaWhenEnumAccessesStaticFieldFromConstructor() {
    rewriteRun(
      //language=java
      java(
        """
          import java.time.LocalDate;
          import java.time.format.DateTimeFormatter;
          enum Test {
              A, B;

              private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");

              Test() {
                  Runnable r = new Runnable() {
                      @Override
                      public void run() {
                          DATE_FORMAT.format(LocalDate.now());
                      }
                  };
              }
          }
          """
      )
    );
}

What did you expect to see?

No code change (so anonymous class should not be converted).

What did you see instead?

A conversion:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
enum Test {
    A, B;

    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    Test() {
        Runnable r = () -> DATE_FORMAT.format(LocalDate.now());
    }
}

which leads to compile error: Accessing static field from enum constructor is not allowed.

Extra info

The reason this error message appears: static fields in anonymous classes in the constructor are valid, but the same is not true for lambdas. This is because the loading order of enums is different from that of classes:

image
@jevanlingen jevanlingen added the bug Something isn't working label Dec 24, 2024
@timtebeek timtebeek moved this to Backlog in OpenRewrite Dec 24, 2024
@timtebeek timtebeek changed the title UseLambdaForFunctionalInterface should not convert when code uses a static field from enum constructor UseLambdaForFunctionalInterface should not convert when code uses a static field from enum constructor Dec 24, 2024
@jevanlingen jevanlingen self-assigned this Dec 24, 2024
@github-project-automation github-project-automation bot moved this from Backlog to Done in OpenRewrite Dec 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working test provided
Projects
Archived in project
2 participants