-
Notifications
You must be signed in to change notification settings - Fork 516
Description
There is a really subtle problem with how Visitor, Cursor, and JavaTemplate interact that potentially affects many recipes.
In circumstances like these templating can fail:
- Visitor calls
super.visitX()(or otherwise modifies an AST, but this is common) - The AST element returned by
super.visitX()is different than AST element passed intosuper.visitX() - JavaTemplate is used on the new AST element returned by
super.visitX() - During templating,
BlockStatementTemplateGenerator.template()makes a comparison ofpriorto the AST element returned from the call tosuper.visitX()
BlockStatementTemplateGenerator uses the Cursor to look up the AST elements surrounding the element you're templating. So that it can generate a valid Java snippet with all of the appropriate variables in scope.
So say you called super.visitNewClass() on an instantiation passed as an argument to a method. We operate on immutable data structures, so the method invocation containing that is unchanged.
BlockStatementTemplateGenerator will use the Cursor to look up the old J.MethodInvocation that does not have the updated argument from the call to super.visitNewClass().
BlockStatementTemplateGenerater.template() knows that the thing its templating is some part of a J.MethodInvocation, and tries to figure out which part so it can construct an appropriate snippet to contain it. But because it is comparing the old J.MethodInvocation's arguments with an element not contained in that argument list, the comparison fails and a correct snippet is not generated.
So this is most likely to be an issue with recipes that use JavaTemplate on AST elements that can contain elements of the same type. i.e.: Recipes which modify MethodDeclaration, MethodInvocation, NewClass, ClassDeclaration, Body, Lambda, etc.
First noticed this
Metadata
Metadata
Assignees
Labels
Type
Projects
Status