I was writing a recipe that replaces one statement with other multiple ones using a JavaTemplate but I couldn't make it work.
After investigating, I realized that changing only one statement with only another one worked fine, the problem came when I tried to replace one statement with multiple ones.
The error I saw was that it didn't build well the statement. In my case I was trying to substitute one mocking statement with two mocking statements. While the first mocking statement was well written the second one seemed to be wrongly parsed.
Here is a code snippet of how code looked after applying the recipe:
given(methodToMock1).willReturn(expectedResponse1);
Templategiven(methodToMock2 <error>();
After trying other things I also saw an error telling me that I was trying to substitute one statement with two and that doing this is not valid.
WHAT I HAVE TRIED:
I tried applying the JavaTemplate doing the following:
Note: In the example I show below oldMockStatement
refers to the mock statement I want to replace (is only one statement) and methodDeclarationWhereApplyingChanges
refers to the method where this changes are being applied:
// New mocks we want to include
String NEW_MOCK_STATEMENTS =
"""
given(methodToMock1).willReturn(expectedResponse1);
given(methodToMock2).willReturn(expectedResponse2);
""";
// Building JavaTemplate
JavaTemplate javaTemplate = JavaTemplate.builder(NEW_MOCK_STATEMENTS).build();
// We replace old mock statement with two new ones
methodDeclarationWhereApplyingChanges = methodDeclarationWhereApplyingChanges.withBody(
javaTemplate.apply(
new Cursor(getCursor(), methodDeclarationWhereApplyingChanges.getBody()),
oldMockStatement.getCoordinates().replace()));
MY QUESTION:
Using OpenRewrite what is the correct approach for substituting one statement with multiple ones? Are there any examples?
Conceptually, you will want to modify or replace a single LST element with a single other LST element, anywhere up the hierarchy. This limitation is most easily realized when you try to assign the result of JavaTemplate apply(..)
to a local variable: You'll need to assign it to some class that extends org.openrewrite.java.tree.J
.
What you can do though is either modify/extend the statements contained in the parent block, or introduce a new block containing two statements, and then doAfterVisit(new RemoveUnneededBlock().getVisitor())
to remove the surrounding braces.
I hope that helps! Also welcome to join our Slack, linked from the top of the docs is that's more convenient for any follow up questions.