Skip to content

UseLambdaForFunctionalInterface produces invalid diamond-operator cast when converting anonymous class using diamond with new #892

@protocol7

Description

@protocol7

What version of OpenRewrite are you using?

  • rewrite-static-analysis: 2.34.1
  • rewrite-core: 8.81.13
  • rewrite-java: 8.81.13

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

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer;

import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

class Main {
  void setup(Object mock) {
    doAnswer(
            new Answer<>() {
              @Override
              public Object answer(InvocationOnMock invocation) throws Throwable {
                return null;
              }
            })
        .when(mock);
  }
}

Run org.openrewrite.staticanalysis.UseLambdaForFunctionalInterface.

What did you expect to see?

Either no change, or a valid lambda conversion such as:

doAnswer((Answer<Object>) invocation -> null)
    .when(mock);

The diamond operator <> is only valid after new (JLS 15.9), not in a cast expression (JLS 15.16).

What did you see instead?

The recipe converts the anonymous inner class to a lambda with a diamond-operator cast:

doAnswer((Answer<>) invocation -> {
          return null;
        })
    .when(mock);

(Answer<>) is not valid Java. The diamond operator cannot appear in a cast expression.

What is the full stack trace of any errors you encountered?

Downstream formatting/parsing fails with:

Main.java:44:25: error: illegal start of type
                (Answer<>) invocation -> {
                        ^

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions