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

VarAccess raises TraitErrorsException for accesses in lambda expressions #31

Closed
aaronist opened this issue Aug 31, 2023 · 1 comment · Fixed by #37
Closed

VarAccess raises TraitErrorsException for accesses in lambda expressions #31

aaronist opened this issue Aug 31, 2023 · 1 comment · Fixed by #37
Labels
bug Something isn't working

Comments

@aaronist
Copy link
Contributor

At the moment, there is no support in OpenRewrite for handling variable accesses within lambda expressions, causing the following test cases to fail:

@Test
void lambdaException() {
    rewriteRun(
      java(
        """
          import java.util.concurrent.FutureTask;
          
          class Test {
              void foobar() {
                  FutureTask<Exception> task = new FutureTask<>(() -> {
                      try {
                          return null;
                      } catch (Exception e) {
                          return e;
                      }
                  });
              }
          }
          """
      )
    );
}

with the exception:

Caused by: org.openrewrite.analysis.trait.util.TraitErrorsException: TraitErrors: 
	- Method must be created from class org.openrewrite.java.tree.J$MethodDeclaration but was class org.openrewrite.java.tree.J$ControlParentheses
	- InstanceInitializer must be created from class org.openrewrite.java.tree.J$Block but was class org.openrewrite.java.tree.J$Lambda
	- Field must be declared in a class, interface, or anonymous class
	at org.openrewrite.analysis.trait.util.TraitErrors.doThrow(TraitErrors.java:43)
	at fj.data.Either$RightProjection.on(Either.java:531)
	at fj.data.Validation.on(Validation.java:146)
	at org.openrewrite.analysis.trait.expr.VarAccessBase$1.visitVariable(VarAccess.java:190)
	at org.openrewrite.analysis.trait.expr.VarAccessBase$1.visitVariable(VarAccess.java:178)
	at org.openrewrite.java.tree.J$VariableDeclarations$NamedVariable.acceptJava(J.java:5627)
	at org.openrewrite.java.tree.J.accept(J.java:59)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:278)
	...

and the test:

@Test
void lambdaNewInstance() {
    rewriteRun(
      java(
        """
          class A {
              static A newInstance() {
                  return new A();
              }
          }
          
          class Test {
              ThreadLocal<A> foobar =
                  ThreadLocal.withInitial(() -> {
                      A a = A.newInstance();
                      return a;
                  });
          }
          """
      )
    );
}

with the exception:

Caused by: org.openrewrite.analysis.trait.util.TraitErrorsException: TraitErrors: 
	- Method must be created from class org.openrewrite.java.tree.J$MethodDeclaration but was class org.openrewrite.java.tree.J$Block
	- No parent Method found
	- Field must be declared in a class, interface, or anonymous class
	at org.openrewrite.analysis.trait.util.TraitErrors.doThrow(TraitErrors.java:43)
	at fj.data.Either$RightProjection.on(Either.java:531)
	at fj.data.Validation.on(Validation.java:146)
	at org.openrewrite.analysis.trait.expr.VarAccessBase$1.visitVariable(VarAccess.java:190)
	at org.openrewrite.analysis.trait.expr.VarAccessBase$1.visitVariable(VarAccess.java:178)
	at org.openrewrite.java.tree.J$VariableDeclarations$NamedVariable.acceptJava(J.java:5627)
	at org.openrewrite.java.tree.J.accept(J.java:59)
	at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:278)
	...

In the future, this may involve adding a LambdaExpr trait to the trait API in rewrite-analysis to distinguish lambda expressions.

@aaronist aaronist added the bug Something isn't working label Aug 31, 2023
@timtebeek timtebeek moved this to Backlog in OpenRewrite Aug 31, 2023
knutwannheden added a commit that referenced this issue Nov 8, 2023
The lambda support is basically already there. What was missing for the existing `LambdaTest` test case was that the iteration in `LocalVariableDecl#findNearestParentCallable()` stopped on any constructor invocation, rather than only when iterating out of the body of an anonymous subclasses.

Fixes: #31
@github-project-automation github-project-automation bot moved this from Backlog to Done in OpenRewrite Nov 8, 2023
@knutwannheden
Copy link
Contributor

As noted in the linked PR the issue was mostly linked to the handling of anonymous subclasses.

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.

2 participants