ast package - go/ast - Go Packages
Package ast declares the types used to represent syntax trees for Go packages.
Syntax trees may be constructed directly, but they are typically produced from Go source code by the parser; see the ParseFile function in package go/parser.
- func FileExports(src *File) bool
- func FilterDecl(decl Decl, f Filter) bool
- func FilterFile(src *File, f Filter) bool
- func FilterPackage(pkg *Package, f Filter) booldeprecated
- func Fprint(w io.Writer, fset *token.FileSet, x any, f FieldFilter) error
- func Inspect(node Node, f func(Node) bool)
- func IsExported(name string) bool
- func IsGenerated(file *File) bool
- func NotNilFilter(_ string, v reflect.Value) bool
- func PackageExports(pkg *Package) booldeprecated
- func Preorder(root Node) iter.Seq[Node]
- func PreorderStack(root Node, stack []Node, f func(n Node, stack []Node) bool)
- func Print(fset *token.FileSet, x any) error
- func SortImports(fset *token.FileSet, f *File)
- func Walk(v Visitor, node Node)
- type ArrayType
- type AssignStmt
- type BadDecl
- type BadExpr
- type BadStmt
- type BasicLit
- type BinaryExpr
- type BlockStmt
- type BranchStmt
- type CallExpr
- type CaseClause
- type ChanDir
- type ChanType
- type CommClause
- type Comment
- type CommentGroup
- type CommentMap
- type CompositeLit
- type Decl
- type DeclStmt
- type DeferStmt
- type Directive
- type DirectiveArg
- type Ellipsis
- type EmptyStmt
- type Expr
- type ExprStmt
- type Field
- type FieldFilter
- type FieldList
- type File
- type Filter
- type ForStmt
- type FuncDecl
- type FuncLit
- type FuncType
- type GenDecl
- type GoStmt
- type Ident
- type IfStmt
- type ImportSpec
- type Importerdeprecated
- type IncDecStmt
- type IndexExpr
- type IndexListExpr
- type InterfaceType
- type KeyValueExpr
- type LabeledStmt
- type MapType
- type MergeModedeprecated
- type Node
- type ObjKind
- type Objectdeprecated
- type Packagedeprecated
- type ParenExpr
- type RangeStmt
- type ReturnStmt
- type Scopedeprecated
- type SelectStmt
- type SelectorExpr
- type SendStmt
- type SliceExpr
- type Spec
- type StarExpr
- type Stmt
- type StructType
- type SwitchStmt
- type TypeAssertExpr
- type TypeSpec
- type TypeSwitchStmt
- type UnaryExpr
- type ValueSpec
- type Visitor
This section is empty.
This section is empty.
FileExports trims the AST for a Go source file in place such that only exported nodes remain: all top-level identifiers which are not exported and their associated information (such as type, initial value, or function body) are removed. Non-exported fields and methods of exported types are stripped. The [File.Comments] list is not changed.
FileExports reports whether there are exported declarations.
FilterDecl trims the AST for a Go declaration in place by removing all names (including struct field and interface method names, but not from parameter lists) that don't pass through the filter f.
FilterDecl reports whether there are any declared names left after filtering.
FilterFile trims the AST for a Go file in place by removing all names from top-level declarations (including struct field and interface method names, but not from parameter lists) that don't pass through the filter f. If the declaration is empty afterwards, the declaration is removed from the AST. Import declarations are always removed. The [File.Comments] list is not changed.
FilterFile reports whether there are any top-level declarations left after filtering.
FilterPackage trims the AST for a Go package in place by removing all names from top-level declarations (including struct field and interface method names, but not from parameter lists) that don't pass through the filter f. If the declaration is empty afterwards, the declaration is removed from the AST. The pkg.Files list is not changed, so that file names and top-level package comments don't get lost.
FilterPackage reports whether there are any top-level declarations left after filtering.
Deprecated: use the type checker go/types instead of Package; see Object. Alternatively, use FilterFile.
Fprint prints the (sub-)tree starting at AST node x to w. If fset != nil, position information is interpreted relative to that file set. Otherwise positions are printed as integer values (file set specific offsets).
A non-nil FieldFilter f may be provided to control the output: struct fields for which f(fieldname, fieldvalue) is true are printed; all others are filtered from the output. Unexported struct fields are never printed.
Inspect traverses an AST in depth-first order: It starts by calling f(node); node must not be nil. If f returns true, Inspect invokes f recursively for each of the non-nil children of node, followed by a call of f(nil).
In many cases it may be more convenient to use Preorder, which returns an iterator over the sequence of nodes, or PreorderStack, which (like Inspect) provides control over descent into subtrees, but additionally reports the stack of enclosing nodes.
This example demonstrates how to inspect the AST of a Go program.
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
)
func main() {
// src is the input for which we want to inspect the AST.
src := `
package p
const c = 1.0
var X = f(3.14)*2 + c
`
// Create the AST by parsing src.
fset := token.NewFileSet() // positions are relative to fset
f, err := parser.ParseFile(fset, "src.go", src, 0)
if err != nil {
panic(err)
}
// Inspect the AST and print all identifiers and literals.
ast.Inspect(f, func(n ast.Node) bool {
var s string
switch x := n.(type) {
case *ast.BasicLit:
s = x.Value
case *ast.Ident:
s = x.Name
}
if s != "" {
fmt.Printf("%s:\t%s\n", fset.Position(n.Pos()), s)
}
return true
})
}
Output: src.go:2:9: p src.go:3:7: c src.go:3:11: 1.0 src.go:4:5: X src.go:4:9: f src.go:4:11: 3.14 src.go:4:17: 2 src.go:4:21: c
IsExported reports whether name starts with an upper-case letter.
IsGenerated reports whether the file was generated by a program, not handwritten, by detecting the special comment described at https://go.dev/s/generatedcode.
The syntax tree must have been parsed with the [parser.ParseComments] flag. Example:
f, err := parser.ParseFile(fset, filename, src, parser.ParseComments|parser.PackageClauseOnly)
if err != nil { ... }
gen := ast.IsGenerated(f)
NotNilFilter is a FieldFilter that returns true for field values that are not nil; it returns false otherwise.
PackageExports trims the AST for a Go package in place such that only exported nodes remain. The pkg.Files list is not changed, so that file names and top-level package comments don't get lost.
PackageExports reports whether there are exported declarations; it returns false otherwise.
Deprecated: use the type checker go/types instead of Package; see Object. Alternatively, use FileExports.
Preorder returns an iterator over all the nodes of the syntax tree beneath (and including) the specified root, in depth-first preorder.
For greater control over the traversal of each subtree, use Inspect or PreorderStack.
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
)
func main() {
src := `
package p
func f(x, y int) {
print(x + y)
}
`
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", src, 0)
if err != nil {
panic(err)
}
// Print identifiers in order
for n := range ast.Preorder(f) {
id, ok := n.(*ast.Ident)
if !ok {
continue
}
fmt.Println(id.Name)
}
}
Output: p f x y int print x y
PreorderStack traverses the tree rooted at root, calling f before visiting each node.
Each call to f provides the current node and traversal stack, consisting of the original value of stack appended with all nodes from root to n, excluding n itself. (This design allows calls to PreorderStack to be nested without double counting.)
If f returns false, the traversal skips over that subtree. Unlike Inspect, no second call to f is made after visiting node n. (In practice, the second call is nearly always used only to pop the stack, and it is surprisingly tricky to do this correctly.)
Print prints x to standard output, skipping nil fields. Print(fset, x) is the same as Fprint(os.Stdout, fset, x, NotNilFilter).
This example shows what an AST looks like when printed for debugging.
package main
import (
"go/ast"
"go/parser"
"go/token"
)
func main() {
// src is the input for which we want to print the AST.
src := `
package main
func main() {
println("Hello, World!")
}
`
// Create the AST by parsing src.
fset := token.NewFileSet() // positions are relative to fset
f, err := parser.ParseFile(fset, "", src, 0)
if err != nil {
panic(err)
}
// Print the AST.
ast.Print(fset, f)
}
Output: 0 *ast.File { 1 . Package: 2:1 2 . Name: *ast.Ident { 3 . . NamePos: 2:9 4 . . Name: "main" 5 . } 6 . Decls: []ast.Decl (len = 1) { 7 . . 0: *ast.FuncDecl { 8 . . . Name: *ast.Ident { 9 . . . . NamePos: 3:6 10 . . . . Name: "main" 11 . . . . Obj: *ast.Object { 12 . . . . . Kind: func 13 . . . . . Name: "main" 14 . . . . . Decl: *(obj @ 7) 15 . . . . } 16 . . . } 17 . . . Type: *ast.FuncType { 18 . . . . Func: 3:1 19 . . . . Params: *ast.FieldList { 20 . . . . . Opening: 3:10 21 . . . . . Closing: 3:11 22 . . . . } 23 . . . } 24 . . . Body: *ast.BlockStmt { 25 . . . . Lbrace: 3:13 26 . . . . List: []ast.Stmt (len = 1) { 27 . . . . . 0: *ast.ExprStmt { 28 . . . . . . X: *ast.CallExpr { 29 . . . . . . . Fun: *ast.Ident { 30 . . . . . . . . NamePos: 4:2 31 . . . . . . . . Name: "println" 32 . . . . . . . } 33 . . . . . . . Lparen: 4:9 34 . . . . . . . Args: []ast.Expr (len = 1) { 35 . . . . . . . . 0: *ast.BasicLit { 36 . . . . . . . . . ValuePos: 4:10 37 . . . . . . . . . ValueEnd: 4:25 38 . . . . . . . . . Kind: STRING 39 . . . . . . . . . Value: "\"Hello, World!\"" 40 . . . . . . . . } 41 . . . . . . . } 42 . . . . . . . Ellipsis: - 43 . . . . . . . Rparen: 4:25 44 . . . . . . } 45 . . . . . } 46 . . . . } 47 . . . . Rbrace: 5:1 48 . . . } 49 . . } 50 . } 51 . FileStart: 1:1 52 . FileEnd: 5:3 53 . Scope: *ast.Scope { 54 . . Objects: map[string]*ast.Object (len = 1) { 55 . . . "main": *(obj @ 11) 56 . . } 57 . } 58 . Unresolved: []*ast.Ident (len = 1) { 59 . . 0: *(obj @ 29) 60 . } 61 . GoVersion: "" 62 }
SortImports sorts runs of consecutive import lines in import blocks in f. It also removes duplicate imports when it is possible to do so without data loss.
Walk traverses an AST in depth-first order: It starts by calling v.Visit(node); node must not be nil. If the visitor w returned by v.Visit(node) is not nil, Walk is invoked recursively with visitor w for each of the non-nil children of node, followed by a call of w.Visit(nil).
An ArrayType node represents an array or slice type.
An AssignStmt node represents an assignment or a short variable declaration.
A BadDecl node is a placeholder for a declaration containing syntax errors for which a correct declaration node cannot be created.
A BadExpr node is a placeholder for an expression containing syntax errors for which a correct expression node cannot be created.
A BadStmt node is a placeholder for statements containing syntax errors for which no correct statement nodes can be created.
A BasicLit node represents a literal of basic type.
Note that for the CHAR and STRING kinds, the literal is stored with its quotes. For example, for a double-quoted STRING, the first and the last rune in the Value field will be ". The strconv.Unquote and strconv.UnquoteChar functions can be used to unquote STRING and CHAR values, respectively.
For raw string literals (Kind == token.STRING && Value[0] == '`'), the Value field contains the string text without carriage returns (\r) that may have been present in the source.
A BinaryExpr node represents a binary expression.
A BlockStmt node represents a braced statement list.
A BranchStmt node represents a break, continue, goto, or fallthrough statement.
A CallExpr node represents an expression followed by an argument list.
A CaseClause represents a case of an expression or type switch statement.
type ChanDir ΒΆ
The direction of a channel type is indicated by a bit mask including one or both of the following constants.
A ChanType node represents a channel type.
A CommClause node represents a case of a select statement.
A Comment node represents a single //-style or /*-style comment.
The Text field contains the comment text without carriage returns (\r) that may have been present in the source. Because a comment's end position is computed using len(Text), the position reported by Comment.End does not match the true source end position for comments containing carriage returns.
type CommentGroup struct {
}
A CommentGroup represents a sequence of comments with no other tokens and no empty lines between.
Text returns the text of the comment. Comment markers (//, /*, and */), the first space of a line comment, and leading and trailing empty lines are removed. Comment directives like "//line" and "//go:noinline" are also removed. Multiple empty lines are reduced to one, and trailing space on lines is trimmed. Unless the result is empty, it is newline-terminated.
type CommentMap map[Node][]*CommentGroup
A CommentMap maps an AST node to a list of comment groups associated with it. See NewCommentMap for a description of the association.
NewCommentMap creates a new comment map by associating comment groups of the comments list with the nodes of the AST specified by node.
A comment group g is associated with a node n if:
- g starts on the same line as n ends
- g starts on the line immediately following n, and there is at least one empty line after g and before the next node
- g starts before n and is not associated to the node before n via the previous rules
NewCommentMap tries to associate a comment group to the "largest" node possible: For instance, if the comment is a line comment trailing an assignment, the comment is associated with the entire assignment rather than just the last operand in the assignment.
func (cmap CommentMap) Comments() []*CommentGroup
Comments returns the list of comment groups in the comment map. The result is sorted in source order.
func (cmap CommentMap) Filter(node Node) CommentMap
Filter returns a new comment map consisting of only those entries of cmap for which a corresponding node exists in the AST specified by node.
func (cmap CommentMap) Update(old, new Node) Node
Update replaces an old node in the comment map with the new node and returns the new node. Comments that were associated with the old node are associated with the new node.
A CompositeLit node represents a composite literal.
type Decl interface {
Node
}
All declaration nodes implement the Decl interface.
type DeclStmt struct {
Decl Decl
}
A DeclStmt node represents a declaration in a statement list.
A DeferStmt node represents a defer statement.
A Directive is a comment of this form:
//tool:name args
For example, this directive:
//go:generate stringer -type Op -trimprefix Op
would have Tool "go", Name "generate", and Args "stringer -type Op -trimprefix Op".
While Args does not have a strict syntax, by convention it is a space-separated sequence of unquoted words, '"'-quoted Go strings, or '`'-quoted raw strings.
See https://go.dev/doc/comment#directives for specification.
ParseDirective parses a single comment line for a directive comment.
If the line is not a directive comment, it returns false.
The provided text must be a single line and should include the leading "//". If the text does not start with "//", it returns false.
The caller may provide a file position of the start of c. This will be used to track the position of the arguments. This may be [Comment.Slash], synthesized by the caller, or simply 0. If the caller passes 0, then the positions are effectively byte offsets into the string c.
ParseArgs parses a Directive's arguments using the standard convention, which is a sequence of tokens, where each token may be a bare word, or a double quoted Go string, or a back quoted raw Go string. Each token must be separated by one or more Unicode spaces.
If the arguments do not conform to this syntax, it returns an error.
A DirectiveArg is an argument to a directive comment.
An Ellipsis node stands for the "..." type in a parameter list or the "..." length in an array type.
An EmptyStmt node represents an empty statement. The "position" of the empty statement is the position of the immediately following (explicit or implicit) semicolon.
type Expr interface {
Node
}
All expression nodes implement the Expr interface.
type ExprStmt struct {
X Expr
}
An ExprStmt node represents a (stand-alone) expression in a statement list.
type Field struct {
Doc *CommentGroup
Names []*Ident
Type Expr
Tag *BasicLit
}
A Field represents a Field declaration list in a struct type, a method list in an interface type, or a parameter/result declaration in a signature. [Field.Names] is nil for unnamed parameters (parameter lists which only contain types) and embedded struct fields. In the latter case, the field name is the type name.
A FieldFilter may be provided to Fprint to control the output.
A FieldList represents a list of Fields, enclosed by parentheses, curly braces, or square brackets.
type File struct {
Doc *CommentGroup
Package token.Pos
Name *Ident
Decls []Decl
FileStart, FileEnd token.Pos
Scope *Scope
Imports []*ImportSpec
Unresolved []*Ident
GoVersion string
}
A File node represents a Go source file.
The Comments list contains all comments in the source file in order of appearance, including the comments that are pointed to from other nodes via Doc and Comment fields.
For correct printing of source code containing comments (using packages go/format and go/printer), special care must be taken to update comments when a File's syntax tree is modified: For printing, comments are interspersed between tokens based on their position. If syntax tree nodes are removed or moved, relevant comments in their vicinity must also be removed (from the [File.Comments] list) or moved accordingly (by updating their positions). A CommentMap may be used to facilitate some of these operations.
Whether and how a comment is associated with a node depends on the interpretation of the syntax tree by the manipulating program: except for Doc and Comment comments directly associated with nodes, the remaining comments are "free-floating" (see also issues #18593, #20744).
End returns the end of the last declaration in the file. It may be invalid, for example in an empty file.
(Use FileEnd for the end of the entire file. It is always valid.)
Pos returns the position of the package declaration. It may be invalid, for example in an empty file.
(Use FileStart for the start of the entire file. It is always valid.)
A ForStmt represents a for statement.
type FuncDecl struct {
Doc *CommentGroup
Recv *FieldList
Name *Ident
Type *FuncType
Body *BlockStmt
}
A FuncDecl node represents a function declaration.
A FuncLit node represents a function literal.
A FuncType node represents a function type.
A GenDecl node (generic declaration node) represents an import, constant, type or variable declaration. A valid Lparen position (Lparen.IsValid()) indicates a parenthesized declaration.
Relationship between Tok value and Specs element type:
token.IMPORT *ImportSpec token.CONST *ValueSpec token.TYPE *TypeSpec token.VAR *ValueSpec
A GoStmt node represents a go statement.
An Ident node represents an identifier.
NewIdent creates a new Ident without position. Useful for ASTs generated by code other than the Go parser.
An IfStmt node represents an if statement.
type ImportSpec struct {
Doc *CommentGroup
Name *Ident
Path *BasicLit
EndPos token.Pos
}
An ImportSpec node represents a single package import.
An Importer resolves import paths to package Objects. The imports map records the packages already imported, indexed by package id (canonical import path). An Importer must determine the canonical import path and check the map to see if it is already present in the imports map. If so, the Importer can return the map entry. Otherwise, the Importer should load the package data for the given path into a new *Object (pkg), record pkg in the imports map, and then return pkg.
Deprecated: use the type checker go/types instead; see Object.
An IncDecStmt node represents an increment or decrement statement.
An IndexExpr node represents an expression followed by an index.
An IndexListExpr node represents an expression followed by multiple indices.
An InterfaceType node represents an interface type.
A KeyValueExpr node represents (key : value) pairs in composite literals.
A LabeledStmt node represents a labeled statement.
The MergeMode flags control the behavior of MergePackageFiles.
Deprecated: use the type checker go/types instead of Package; see Object.
All node types implement the Node interface.
ObjKind describes what an Object represents.
An Object describes a named language entity such as a package, constant, type, variable, function (incl. methods), or label.
The Data fields contains object-specific data:
Kind Data type Data value Pkg *Scope package scope Con int iota for the respective declaration
Deprecated: The relationship between Idents and Objects cannot be correctly computed without type information. For example, the expression T{K: 0} may denote a struct, map, slice, or array literal, depending on the type of T. If T is a struct, then K refers to a field of T, whereas for the other types it refers to a value in the environment.
New programs should set the [parser.SkipObjectResolution] parser flag to disable syntactic object resolution (which also saves CPU and memory), and instead use the type checker go/types if object resolution is desired. See the Defs, Uses, and Implicits fields of the [types.Info] struct for details.
NewObj creates a new object of a given kind and name.
Pos computes the source position of the declaration of an object name. The result may be an invalid position if it cannot be computed (obj.Decl may be nil or not correct).
A Package node represents a set of source files collectively building a Go package.
Deprecated: use the type checker go/types instead; see Object.
NewPackage creates a new Package node from a set of File nodes. It resolves unresolved identifiers across files and updates each file's Unresolved list accordingly. If a non-nil importer and universe scope are provided, they are used to resolve identifiers not declared in any of the package files. Any remaining unresolved identifiers are reported as undeclared. If the files belong to different packages, one package name is selected and files with different package names are reported and then ignored. The result is a package node and a scanner.ErrorList if there were errors.
Deprecated: use the type checker go/types instead; see Object.
A ParenExpr node represents a parenthesized expression.
A RangeStmt represents a for statement with a range clause.
A ReturnStmt node represents a return statement.
A Scope maintains the set of named language entities declared in the scope and a link to the immediately surrounding (outer) scope.
Deprecated: use the type checker go/types instead; see Object.
Insert attempts to insert a named object obj into the scope s. If the scope already contains an object alt with the same name, Insert leaves the scope unchanged and returns alt. Otherwise it inserts obj and returns nil.
Lookup returns the object with the given name if it is found in scope s, otherwise it returns nil. Outer scopes are ignored.
A SelectStmt node represents a select statement.
A SelectorExpr node represents an expression followed by a selector.
A SendStmt node represents a send statement.
A SliceExpr node represents an expression followed by slice indices.
type Spec interface {
Node
}
The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
A StarExpr node represents an expression of the form "*" Expression. Semantically it could be a unary "*" expression, or a pointer type.
type Stmt interface {
Node
}
All statement nodes implement the Stmt interface.
A StructType node represents a struct type.
A SwitchStmt node represents an expression switch statement.
A TypeAssertExpr node represents an expression followed by a type assertion.
type TypeSpec struct {
Doc *CommentGroup
Name *Ident
TypeParams *FieldList
Assign token.Pos
Type Expr
}
A TypeSpec node represents a type declaration (TypeSpec production).
A TypeSwitchStmt node represents a type switch statement.
A UnaryExpr node represents a unary expression. Unary "*" expressions are represented via StarExpr nodes.
type ValueSpec struct {
Doc *CommentGroup
Names []*Ident
Type Expr
Values []Expr
}
A ValueSpec node represents a constant or variable declaration (ConstSpec or VarSpec production).