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

FlowPath analysis doesn't work with Chained Lambda expressions. #72

Closed
amishra-u opened this issue Dec 7, 2024 · 0 comments · Fixed by #73
Closed

FlowPath analysis doesn't work with Chained Lambda expressions. #72

amishra-u opened this issue Dec 7, 2024 · 0 comments · Fixed by #73
Labels
bug Something isn't working

Comments

@amishra-u
Copy link
Contributor

What version of OpenRewrite are you using?

Verified the issue on rewrite-analysis head and latest-release 2.13.1

How are you running OpenRewrite?

Confirmed the bug by writing unit-test in rewrite-analysis.

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

Flow path analysis currently fails for chained lambda expressions. The issue arises because the lambda end is marked as ControlFlowNode.End, causing subsequent lambdas in the chain to be skipped.

Added below unit-test to the FindLocalFlowPathsNumericTest class to confirm the issue:

@Test
    void flowPathDetectionWithChainedLambdas() {
        //language=java
        rewriteRun(
          spec -> spec.expectedCyclesThatMakeChanges(1).cycles(1),
          java(
            """
              import java.util.List;
              import java.util.stream.Stream;

              class Test {
                  void test() {
                      List<Integer> list = Stream.of(1, 2, 3).peek(i -> {
                          System.out.println("Number " + i);
                      }).peek(i -> {
                          int n = 42;
                          int o = n;
                          System.out.println(o);
                          int p = o;
                      }).toList();
                  }
              }
              """, """
              import java.util.List;
              import java.util.stream.Stream;

              class Test {
                  void test() {
                      List<Integer> list = Stream.of(1, 2, 3).peek(i -> {
                          System.out.println("Number " + i);
                      }).peek(i -> {
                          int n = /*~~>*/42;
                          int o = /*~~>*/n;
                          System.out.println(/*~~>*/o);
                          int p = /*~~>*/o;
                      }).toList();
                  }
              }
              """
          )
        );
    }

What did you expect to see?

The test should pass, with flow paths properly detected and marked in the chained lambda expressions.

What did you see instead?

The recipe fails to make any changes, as the flow path detection skips subsequent lambdas in the chain.

Solution:

The current implementation marks the parent method body as the start node when identifying flow paths for expressions inside a lambda body. Instead, the lambda body itself should be marked as the start node. This approach aligns with JLS §15.27.2, by which we can infer that expressions within a lambda body cannot assign values to variables declared outside of that lambda body.

Are you interested in [contributing a fix to OpenRewrite]

Yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

1 participant