/xast

xast: ast rewriter with built-in clean up.

Primary LanguageGo

xast GoDoc Build Status

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.

Example

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())
}