xast provides Walk()/WalkNode() functions, similar to astrewrite.Walk from the
astrewrite package. The main difference is that the passed walk function can also
check a node's parent.
Also deleting a node will automatically remove any assocociated comments with it.
Note that this is similar to https://go-review.googlesource.com/c/go/+/55790 but the API itself is a lot simpler.
package main import ( "bytes" "fmt" "go/ast" "go/parser" "go/printer" "go/token" "github.com/OneOfOne/xast" ) func main() { src := `package main // Foo is a foo! type Foo struct{} // NotFoo is not a foo! type NotFoo struct{} ` fset := token.NewFileSet() file, err := parser.ParseFile(fset, "foo.go", src, parser.ParseComments) if err != nil { panic(err) } rewriteFn := func(n *xast.Node) *xast.Node { switch x := n.Node().(type) { case *ast.TypeSpec: if x.Name.Name == "Foo" { x.Name.Name = "Bar" } case *ast.CommentGroup: // check n.Text()? x.List = nil return n.Break() // don't delete the node but don't go down it's children list. // or if you want to remove a single comment out of a group case *ast.Comment: // won't ever get here since we return n.Break() from case *ast.CommentGroup. panic("can't get here now") return n.Nil() // delete this node } return n } var buf bytes.Buffer printer.Fprint(&buf, fset, xast.Walk(file, rewriteFn)) fmt.Println(buf.String()) }