Tree. This interface is the foundational contract for all types defined within any abstract syntax tree. A Tree type has the following characteristics:
accept()method that acts as a callback into a language-specific Visitor.
TreeVisitor<T extends Tree, P>from which all of OpenRewrite's visitors extend. It is this class that provides the generic, parameterized
T visit(T, P)method that drives a visitor's polymorphic navigation, cursoring, and life-cycle. The parameterized type
Trepresents the type of tree elements upon which the visitor will navigate and transform. The second parameterized type
Pis an additional, shared context that is passed to all visit methods as a visitor navigates a given AST.
visitClassDeclaration()method being called multiple times. The cursor can be used to determine which class declaration represents the top-level class:
TreeVisitor. As an example, the OpenRewrite language binding for Java is
JavaVisitor. It is on these language-specific source visitors that the visit methods for each AST element are defined along with the language-specific traversal logic.
TreeBuilder.visit(T, P)method is called and how that is mapped into its language-specific counterpart. Let's visualize how a Java CompilationUnit is passed from a client to the visitor:
visit()will result in having the compilation unit's
accept()method executed. The
accept()method will then cast the visitor to the language-specific variant and then call the appropriate, language-specific
visitMethodInvocationis overridden to increment the counter. The JavaVisitor will traverse the AST and call this method each time a method invocation is encountered in the tree.
org.openrewrite.java.tree.Jand all of its language-specific visit methods also return
visitMethodInvocationwill typically return
visitCompilationUnitwill typically return a
J.CompilationUnit, and so on. There are a narrow set of circumstances when this is not true. For example, an UnwrapParentheses visitor might override the
J.Parentheses<?>and can return whatever type of expression is inside the parentheses it is unwrapping.
refactorthat helps you call super and cast the result in one call:
andThen(anotherVisitor). This is useful for building up pipelines of refactoring operations built up of lower-level components. For example, when ChangeFieldType finds a matching field that it is going to transform, it chains together an AddImport visitor to add the new import if necessary, and a RemoveImport to remove the old import if there are no longer any references to it.