Documentation

Overview

    Package astutil contains common utilities for working with the Go AST.

    Index

    Constants

    This section is empty.

    Variables

    This section is empty.

    Functions

    func AddImport

    func AddImport(fset *token.FileSet, f *ast.File, path string) (added bool)

      AddImport adds the import path to the file f, if absent.

      func AddNamedImport

      func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added bool)

        AddNamedImport adds the import with the given name and path to the file f, if absent. If name is not empty, it is used to rename the import.

        For example, calling

        AddNamedImport(fset, f, "pathpkg", "path")
        

        adds

        import pathpkg "path"
        

        func Apply

        func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node)

          Apply traverses a syntax tree recursively, starting with root, and calling pre and post for each node as described below. Apply returns the syntax tree, possibly modified.

          If pre is not nil, it is called for each node before the node's children are traversed (pre-order). If pre returns false, no children are traversed, and post is not called for that node.

          If post is not nil, and a prior call of pre didn't return false, post is called for each node after its children are traversed (post-order). If post returns false, traversal is terminated and Apply returns immediately.

          Only fields that refer to AST nodes are considered children; i.e., token.Pos, Scopes, Objects, and fields of basic types (strings, etc.) are ignored.

          Children are traversed in the order in which they appear in the respective node's struct definition. A package's files are traversed in the filenames' alphabetical order.

          func DeleteImport

          func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool)

            DeleteImport deletes the import path from the file f, if present. If there are duplicate import declarations, all matching ones are deleted.

            func DeleteNamedImport

            func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool)

              DeleteNamedImport deletes the import with the given name and path from the file f, if present. If there are duplicate import declarations, all matching ones are deleted.

              func Imports

              func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec

                Imports returns the file imports grouped by paragraph.

                func NodeDescription

                func NodeDescription(n ast.Node) string

                  NodeDescription returns a description of the concrete type of n suitable for a user interface.

                  TODO(adonovan): in some cases (e.g. Field, FieldList, Ident, StarExpr) we could be much more specific given the path to the AST root. Perhaps we should do that.

                  func PathEnclosingInterval

                  func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool)

                    PathEnclosingInterval returns the node that encloses the source interval [start, end), and all its ancestors up to the AST root.

                    The definition of "enclosing" used by this function considers additional whitespace abutting a node to be enclosed by it. In this example:

                    z := x + y // add them
                         <-A->
                        <----B----->
                    

                    the ast.BinaryExpr(+) node is considered to enclose interval B even though its [Pos()..End()) is actually only interval A. This behaviour makes user interfaces more tolerant of imperfect input.

                    This function treats tokens as nodes, though they are not included in the result. e.g. PathEnclosingInterval("+") returns the enclosing ast.BinaryExpr("x + y").

                    If start==end, the 1-char interval following start is used instead.

                    The 'exact' result is true if the interval contains only path[0] and perhaps some adjacent whitespace. It is false if the interval overlaps multiple children of path[0], or if it contains only interior whitespace of path[0]. In this example:

                    z := x + y // add them
                      <--C-->     <---E-->
                        ^
                        D
                    

                    intervals C, D and E are inexact. C is contained by the z-assignment statement, because it spans three of its children (:=, x, +). So too is the 1-char interval D, because it contains only interior whitespace of the assignment. E is considered interior whitespace of the BlockStmt containing the assignment.

                    Precondition: [start, end) both lie within the same file as root. TODO(adonovan): return (nil, false) in this case and remove precond. Requires FileSet; see loader.tokenFileContainsPos.

                    Postcondition: path is never nil; it always contains at least 'root'.

                    func RewriteImport

                    func RewriteImport(fset *token.FileSet, f *ast.File, oldPath, newPath string) (rewrote bool)

                      RewriteImport rewrites any import of path oldPath to path newPath.

                      func Unparen

                      func Unparen(e ast.Expr) ast.Expr

                        Unparen returns e with any enclosing parentheses stripped.

                        func UsesImport

                        func UsesImport(f *ast.File, path string) (used bool)

                          UsesImport reports whether a given import is used.

                          Types

                          type ApplyFunc

                          type ApplyFunc func(*Cursor) bool

                            An ApplyFunc is invoked by Apply for each node n, even if n is nil, before and/or after the node's children, using a Cursor describing the current node and providing operations on it.

                            The return value of ApplyFunc controls the syntax tree traversal. See Apply for details.

                            type Cursor

                            type Cursor struct {
                            	// contains filtered or unexported fields
                            }

                              A Cursor describes a node encountered during Apply. Information about the node and its parent is available from the Node, Parent, Name, and Index methods.

                              If p is a variable of type and value of the current parent node c.Parent(), and f is the field identifier with name c.Name(), the following invariants hold:

                              p.f            == c.Node()  if c.Index() <  0
                              p.f[c.Index()] == c.Node()  if c.Index() >= 0
                              

                              The methods Replace, Delete, InsertBefore, and InsertAfter can be used to change the AST without disrupting Apply.

                              func (*Cursor) Delete

                              func (c *Cursor) Delete()

                                Delete deletes the current Node from its containing slice. If the current Node is not part of a slice, Delete panics. As a special case, if the current node is a package file, Delete removes it from the package's Files map.

                                func (*Cursor) Index

                                func (c *Cursor) Index() int

                                  Index reports the index >= 0 of the current Node in the slice of Nodes that contains it, or a value < 0 if the current Node is not part of a slice. The index of the current node changes if InsertBefore is called while processing the current node.

                                  func (*Cursor) InsertAfter

                                  func (c *Cursor) InsertAfter(n ast.Node)

                                    InsertAfter inserts n after the current Node in its containing slice. If the current Node is not part of a slice, InsertAfter panics. Apply does not walk n.

                                    func (*Cursor) InsertBefore

                                    func (c *Cursor) InsertBefore(n ast.Node)

                                      InsertBefore inserts n before the current Node in its containing slice. If the current Node is not part of a slice, InsertBefore panics. Apply will not walk n.

                                      func (*Cursor) Name

                                      func (c *Cursor) Name() string

                                        Name returns the name of the parent Node field that contains the current Node. If the parent is a *ast.Package and the current Node is a *ast.File, Name returns the filename for the current Node.

                                        func (*Cursor) Node

                                        func (c *Cursor) Node() ast.Node

                                          Node returns the current Node.

                                          func (*Cursor) Parent

                                          func (c *Cursor) Parent() ast.Node

                                            Parent returns the parent of the current Node.

                                            func (*Cursor) Replace

                                            func (c *Cursor) Replace(n ast.Node)

                                              Replace replaces the current Node with n. The replacement node is not walked by Apply.