To create a Go recipe, embed recipe.Base in a struct, implement Name(), DisplayName(), and Description(), and return a TreeVisitor from the Editor() method.
Critical Patterns:
- Always use
visitor.Init(...): This sets the Self field on the embedded GoVisitor to ensure virtual dispatch works correctly. - Never mutate in place: Always return a fresh value (e.g., a copy of the tree element) instead of mutating the existing one. In-place mutation breaks no-change detection and makes debugging difficult.
package golang
import (
"github.com/openrewrite/rewrite/rewrite-go/pkg/recipe"
"github.com/openrewrite/rewrite/rewrite-go/pkg/tree"
"github.com/openrewrite/rewrite/rewrite-go/pkg/visitor"
)
type RenameXToFlag struct{ recipe.Base }
func (r *RenameXToFlag) Name() string { return "org.openrewrite.golang.test.RenameXToFlag" }
func (r *RenameXToFlag) DisplayName() string { return "Rename x to flag" }
func (r *RenameXToFlag) Description() string { return "Test recipe." }
func (r *RenameXToFlag) Editor() recipe.TreeVisitor {
return visitor.Init(&renameXVisitor{})
}
type renameXVisitor struct{ visitor.GoVisitor }
func (v *renameXVisitor) VisitIdentifier(ident *tree.Identifier, _ any) tree.J {
if ident.Name == "x" {
c := *ident
c.Name = "flag"
return &c
}
return ident
}