Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Package ast declares the types used to represent syntax trees for Go packages.
package ast

import (
	
	
)
---------------------------------------------------------------------------- Interfaces There are 3 main classes of nodes: Expressions and type nodes, statement nodes, and declaration nodes. The node names usually match the corresponding Go spec production names to which they correspond. The node fields correspond to the individual parts of the respective productions. All nodes contain position information marking the beginning of the corresponding source text segment; it is accessible via the Pos accessor method. Nodes may contain additional position info for language constructs where comments may be found between parts of the construct (typically any larger, parenthesized subpart). That position information is needed to properly position comments when printing the construct.
All node types implement the Node interface.
type Node interface {
	Pos() token.Pos // position of first character belonging to the node
	End() token.Pos // position of first character immediately after the node
}
All expression nodes implement the Expr interface.
type Expr interface {
	Node
	exprNode()
}
All statement nodes implement the Stmt interface.
type Stmt interface {
	Node
	stmtNode()
}
All declaration nodes implement the Decl interface.
type Decl interface {
	Node
	declNode()
}
---------------------------------------------------------------------------- Comments
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 End() does not match the true source end position for comments containing carriage returns.
type Comment struct {
	Slash token.Pos // position of "/" starting the comment
	Text  string    // comment text (excluding '\n' for //-style comments)
}

func ( *Comment) () token.Pos { return .Slash }
func ( *Comment) () token.Pos { return token.Pos(int(.Slash) + len(.Text)) }
A CommentGroup represents a sequence of comments with no other tokens and no empty lines between.
type CommentGroup struct {
	List []*Comment // len(List) > 0
}

func ( *CommentGroup) () token.Pos { return .List[0].Pos() }
func ( *CommentGroup) () token.Pos { return .List[len(.List)-1].End() }

func ( byte) bool { return  == ' ' ||  == '\t' ||  == '\n' ||  == '\r' }

func ( string) string {
	 := len()
	for  > 0 && isWhitespace([-1]) {
		--
	}
	return [0:]
}
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.
func ( *CommentGroup) () string {
	if  == nil {
		return ""
	}
	 := make([]string, len(.List))
	for ,  := range .List {
		[] = .Text
	}

	 := make([]string, 0, 10) // most comments are less than 10 lines
Remove comment markers. The parser has given us exactly the comment text.
		switch [1] {
-style comment (no newline at the end)
			 = [2:]
empty line
				break
			}
strip first space - required for Example tests
				 = [1:]
				break
			}
Ignore //go:noinline, //line, and so on.
				continue
			}
-style comment
			 = [2 : len()-2]
		}
Split on newlines.
		 := strings.Split(, "\n")
Walk lines, stripping trailing white space and adding to list.
		for ,  := range  {
			 = append(, stripTrailingWhitespace())
		}
	}
Remove leading blank lines; convert runs of interior blank lines to a single blank line.
	 := 0
	for ,  := range  {
		if  != "" ||  > 0 && [-1] != "" {
			[] = 
			++
		}
	}
	 = [0:]
Add final "" entry to get trailing newline from Join.
	if  > 0 && [-1] != "" {
		 = append(, "")
	}

	return strings.Join(, "\n")
}
isDirective reports whether c is a comment directive.
"//line " is a line directive. (The // has been removed.)
	if strings.HasPrefix(, "line ") {
		return true
	}
"//[a-z0-9]+:[a-z0-9]" (The // has been removed.)
	 := strings.Index(, ":")
	if  <= 0 || +1 >= len() {
		return false
	}
	for  := 0;  <= +1; ++ {
		if  ==  {
			continue
		}
		 := []
		if !('a' <=  &&  <= 'z' || '0' <=  &&  <= '9') {
			return false
		}
	}
	return true
}
---------------------------------------------------------------------------- Expressions and types
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.
type Field struct {
	Doc     *CommentGroup // associated documentation; or nil
	Names   []*Ident      // field/method/parameter names; or nil
	Type    Expr          // field/method/parameter type
	Tag     *BasicLit     // field tag; or nil
	Comment *CommentGroup // line comments; or nil
}

func ( *Field) () token.Pos {
	if len(.Names) > 0 {
		return .Names[0].Pos()
	}
	return .Type.Pos()
}

func ( *Field) () token.Pos {
	if .Tag != nil {
		return .Tag.End()
	}
	return .Type.End()
}
A FieldList represents a list of Fields, enclosed by parentheses or braces.
type FieldList struct {
	Opening token.Pos // position of opening parenthesis/brace, if any
	List    []*Field  // field list; or nil
	Closing token.Pos // position of closing parenthesis/brace, if any
}

func ( *FieldList) () token.Pos {
	if .Opening.IsValid() {
		return .Opening
the list should not be empty in this case; be conservative and guard against bad ASTs
	if len(.List) > 0 {
		return .List[0].Pos()
	}
	return token.NoPos
}

func ( *FieldList) () token.Pos {
	if .Closing.IsValid() {
		return .Closing + 1
the list should not be empty in this case; be conservative and guard against bad ASTs
	if  := len(.List);  > 0 {
		return .List[-1].End()
	}
	return token.NoPos
}
NumFields returns the number of parameters or struct fields represented by a FieldList.
func ( *FieldList) () int {
	 := 0
	if  != nil {
		for ,  := range .List {
			 := len(.Names)
			if  == 0 {
				 = 1
			}
			 += 
		}
	}
	return 
}
An expression is represented by a tree consisting of one or more of the following concrete expression nodes.
A BadExpr node is a placeholder for an expression containing syntax errors for which a correct expression node cannot be created.
	BadExpr struct {
		From, To token.Pos // position range of bad expression
	}
An Ident node represents an identifier.
	Ident struct {
		NamePos token.Pos // identifier position
		Name    string    // identifier name
		Obj     *Object   // denoted object; or nil
	}
An Ellipsis node stands for the "..." type in a parameter list or the "..." length in an array type.
	Ellipsis struct {
		Ellipsis token.Pos // position of "..."
		Elt      Expr      // ellipsis element type (parameter lists only); or nil
	}
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 Unquote and UnquoteChar functions in the strconv package can be used to unquote STRING and CHAR values, respectively.
	BasicLit struct {
		ValuePos token.Pos   // literal position
		Kind     token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
		Value    string      // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o`
	}
A FuncLit node represents a function literal.
	FuncLit struct {
		Type *FuncType  // function type
		Body *BlockStmt // function body
	}
A CompositeLit node represents a composite literal.
	CompositeLit struct {
		Type       Expr      // literal type; or nil
		Lbrace     token.Pos // position of "{"
		Elts       []Expr    // list of composite elements; or nil
		Rbrace     token.Pos // position of "}"
		Incomplete bool      // true if (source) expressions are missing in the Elts list
	}
A ParenExpr node represents a parenthesized expression.
	ParenExpr struct {
		Lparen token.Pos // position of "("
		X      Expr      // parenthesized expression
		Rparen token.Pos // position of ")"
	}
A SelectorExpr node represents an expression followed by a selector.
	SelectorExpr struct {
		X   Expr   // expression
		Sel *Ident // field selector
	}
An IndexExpr node represents an expression followed by an index.
	IndexExpr struct {
		X      Expr      // expression
		Lbrack token.Pos // position of "["
		Index  Expr      // index expression
		Rbrack token.Pos // position of "]"
	}
A SliceExpr node represents an expression followed by slice indices.
	SliceExpr struct {
		X      Expr      // expression
		Lbrack token.Pos // position of "["
		Low    Expr      // begin of slice range; or nil
		High   Expr      // end of slice range; or nil
		Max    Expr      // maximum capacity of slice; or nil
		Slice3 bool      // true if 3-index slice (2 colons present)
		Rbrack token.Pos // position of "]"
	}
A TypeAssertExpr node represents an expression followed by a type assertion.
	TypeAssertExpr struct {
		X      Expr      // expression
		Lparen token.Pos // position of "("
		Type   Expr      // asserted type; nil means type switch X.(type)
		Rparen token.Pos // position of ")"
	}
A CallExpr node represents an expression followed by an argument list.
	CallExpr struct {
		Fun      Expr      // function expression
		Lparen   token.Pos // position of "("
		Args     []Expr    // function arguments; or nil
		Ellipsis token.Pos // position of "..." (token.NoPos if there is no "...")
		Rparen   token.Pos // position of ")"
	}
A StarExpr node represents an expression of the form "*" Expression. Semantically it could be a unary "*" expression, or a pointer type.
	StarExpr struct {
		Star token.Pos // position of "*"
		X    Expr      // operand
	}
A UnaryExpr node represents a unary expression. Unary "*" expressions are represented via StarExpr nodes.
	UnaryExpr struct {
		OpPos token.Pos   // position of Op
		Op    token.Token // operator
		X     Expr        // operand
	}
A BinaryExpr node represents a binary expression.
	BinaryExpr struct {
		X     Expr        // left operand
		OpPos token.Pos   // position of Op
		Op    token.Token // operator
		Y     Expr        // right operand
	}
A KeyValueExpr node represents (key : value) pairs in composite literals.
	KeyValueExpr struct {
		Key   Expr
		Colon token.Pos // position of ":"
		Value Expr
	}
)
The direction of a channel type is indicated by a bit mask including one or both of the following constants.
type ChanDir int

const (
	SEND ChanDir = 1 << iota
	RECV
)
A type is represented by a tree consisting of one or more of the following type-specific expression nodes.
An ArrayType node represents an array or slice type.
	ArrayType struct {
		Lbrack token.Pos // position of "["
		Len    Expr      // Ellipsis node for [...]T array types, nil for slice types
		Elt    Expr      // element type
	}
A StructType node represents a struct type.
	StructType struct {
		Struct     token.Pos  // position of "struct" keyword
		Fields     *FieldList // list of field declarations
		Incomplete bool       // true if (source) fields are missing in the Fields list
	}
Pointer types are represented via StarExpr nodes.
A FuncType node represents a function type.
	FuncType struct {
		Func    token.Pos  // position of "func" keyword (token.NoPos if there is no "func")
		Params  *FieldList // (incoming) parameters; non-nil
		Results *FieldList // (outgoing) results; or nil
	}
An InterfaceType node represents an interface type.
	InterfaceType struct {
		Interface  token.Pos  // position of "interface" keyword
		Methods    *FieldList // list of methods
		Incomplete bool       // true if (source) methods are missing in the Methods list
	}
A MapType node represents a map type.
	MapType struct {
		Map   token.Pos // position of "map" keyword
		Key   Expr
		Value Expr
	}
A ChanType node represents a channel type.
	ChanType struct {
		Begin token.Pos // position of "chan" keyword or "<-" (whichever comes first)
		Arrow token.Pos // position of "<-" (token.NoPos if there is no "<-")
		Dir   ChanDir   // channel direction
		Value Expr      // value type
	}
)
Pos and End implementations for expression/type nodes.

func ( *BadExpr) () token.Pos  { return .From }
func ( *Ident) () token.Pos    { return .NamePos }
func ( *Ellipsis) () token.Pos { return .Ellipsis }
func ( *BasicLit) () token.Pos { return .ValuePos }
func ( *FuncLit) () token.Pos  { return .Type.Pos() }
func ( *CompositeLit) () token.Pos {
	if .Type != nil {
		return .Type.Pos()
	}
	return .Lbrace
}
func ( *ParenExpr) () token.Pos      { return .Lparen }
func ( *SelectorExpr) () token.Pos   { return .X.Pos() }
func ( *IndexExpr) () token.Pos      { return .X.Pos() }
func ( *SliceExpr) () token.Pos      { return .X.Pos() }
func ( *TypeAssertExpr) () token.Pos { return .X.Pos() }
func ( *CallExpr) () token.Pos       { return .Fun.Pos() }
func ( *StarExpr) () token.Pos       { return .Star }
func ( *UnaryExpr) () token.Pos      { return .OpPos }
func ( *BinaryExpr) () token.Pos     { return .X.Pos() }
func ( *KeyValueExpr) () token.Pos   { return .Key.Pos() }
func ( *ArrayType) () token.Pos      { return .Lbrack }
func ( *StructType) () token.Pos     { return .Struct }
func ( *FuncType) () token.Pos {
	if .Func.IsValid() || .Params == nil { // see issue 3870
		return .Func
	}
	return .Params.Pos() // interface method declarations have no "func" keyword
}
func ( *InterfaceType) () token.Pos { return .Interface }
func ( *MapType) () token.Pos       { return .Map }
func ( *ChanType) () token.Pos      { return .Begin }

func ( *BadExpr) () token.Pos { return .To }
func ( *Ident) () token.Pos   { return token.Pos(int(.NamePos) + len(.Name)) }
func ( *Ellipsis) () token.Pos {
	if .Elt != nil {
		return .Elt.End()
	}
	return .Ellipsis + 3 // len("...")
}
func ( *BasicLit) () token.Pos       { return token.Pos(int(.ValuePos) + len(.Value)) }
func ( *FuncLit) () token.Pos        { return .Body.End() }
func ( *CompositeLit) () token.Pos   { return .Rbrace + 1 }
func ( *ParenExpr) () token.Pos      { return .Rparen + 1 }
func ( *SelectorExpr) () token.Pos   { return .Sel.End() }
func ( *IndexExpr) () token.Pos      { return .Rbrack + 1 }
func ( *SliceExpr) () token.Pos      { return .Rbrack + 1 }
func ( *TypeAssertExpr) () token.Pos { return .Rparen + 1 }
func ( *CallExpr) () token.Pos       { return .Rparen + 1 }
func ( *StarExpr) () token.Pos       { return .X.End() }
func ( *UnaryExpr) () token.Pos      { return .X.End() }
func ( *BinaryExpr) () token.Pos     { return .Y.End() }
func ( *KeyValueExpr) () token.Pos   { return .Value.End() }
func ( *ArrayType) () token.Pos      { return .Elt.End() }
func ( *StructType) () token.Pos     { return .Fields.End() }
func ( *FuncType) () token.Pos {
	if .Results != nil {
		return .Results.End()
	}
	return .Params.End()
}
func ( *InterfaceType) () token.Pos { return .Methods.End() }
func ( *MapType) () token.Pos       { return .Value.End() }
func ( *ChanType) () token.Pos      { return .Value.End() }
exprNode() ensures that only expression/type nodes can be assigned to an Expr.
func (*BadExpr) ()        {}
func (*Ident) ()          {}
func (*Ellipsis) ()       {}
func (*BasicLit) ()       {}
func (*FuncLit) ()        {}
func (*CompositeLit) ()   {}
func (*ParenExpr) ()      {}
func (*SelectorExpr) ()   {}
func (*IndexExpr) ()      {}
func (*SliceExpr) ()      {}
func (*TypeAssertExpr) () {}
func (*CallExpr) ()       {}
func (*StarExpr) ()       {}
func (*UnaryExpr) ()      {}
func (*BinaryExpr) ()     {}
func (*KeyValueExpr) ()   {}

func (*ArrayType) ()     {}
func (*StructType) ()    {}
func (*FuncType) ()      {}
func (*InterfaceType) () {}
func (*MapType) ()       {}
func (*ChanType) ()      {}
---------------------------------------------------------------------------- Convenience functions for Idents
NewIdent creates a new Ident without position. Useful for ASTs generated by code other than the Go parser.
func ( string) *Ident { return &Ident{token.NoPos, , nil} }
IsExported reports whether name starts with an upper-case letter.
func ( string) bool { return token.IsExported() }
IsExported reports whether id starts with an upper-case letter.
func ( *Ident) () bool { return token.IsExported(.Name) }

func ( *Ident) () string {
	if  != nil {
		return .Name
	}
	return "<nil>"
}
---------------------------------------------------------------------------- Statements
A statement is represented by a tree consisting of one or more of the following concrete statement nodes.
A BadStmt node is a placeholder for statements containing syntax errors for which no correct statement nodes can be created.
	BadStmt struct {
		From, To token.Pos // position range of bad statement
	}
A DeclStmt node represents a declaration in a statement list.
	DeclStmt struct {
		Decl Decl // *GenDecl with CONST, TYPE, or VAR token
	}
An EmptyStmt node represents an empty statement. The "position" of the empty statement is the position of the immediately following (explicit or implicit) semicolon.
	EmptyStmt struct {
		Semicolon token.Pos // position of following ";"
		Implicit  bool      // if set, ";" was omitted in the source
	}
A LabeledStmt node represents a labeled statement.
	LabeledStmt struct {
		Label *Ident
		Colon token.Pos // position of ":"
		Stmt  Stmt
	}
An ExprStmt node represents a (stand-alone) expression in a statement list.
	ExprStmt struct {
		X Expr // expression
	}
A SendStmt node represents a send statement.
	SendStmt struct {
		Chan  Expr
		Arrow token.Pos // position of "<-"
		Value Expr
	}
An IncDecStmt node represents an increment or decrement statement.
	IncDecStmt struct {
		X      Expr
		TokPos token.Pos   // position of Tok
		Tok    token.Token // INC or DEC
	}
An AssignStmt node represents an assignment or a short variable declaration.
	AssignStmt struct {
		Lhs    []Expr
		TokPos token.Pos   // position of Tok
		Tok    token.Token // assignment token, DEFINE
		Rhs    []Expr
	}
A GoStmt node represents a go statement.
	GoStmt struct {
		Go   token.Pos // position of "go" keyword
		Call *CallExpr
	}
A DeferStmt node represents a defer statement.
	DeferStmt struct {
		Defer token.Pos // position of "defer" keyword
		Call  *CallExpr
	}
A ReturnStmt node represents a return statement.
	ReturnStmt struct {
		Return  token.Pos // position of "return" keyword
		Results []Expr    // result expressions; or nil
	}
A BranchStmt node represents a break, continue, goto, or fallthrough statement.
	BranchStmt struct {
		TokPos token.Pos   // position of Tok
		Tok    token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
		Label  *Ident      // label name; or nil
	}
A BlockStmt node represents a braced statement list.
	BlockStmt struct {
		Lbrace token.Pos // position of "{"
		List   []Stmt
		Rbrace token.Pos // position of "}", if any (may be absent due to syntax error)
	}
An IfStmt node represents an if statement.
	IfStmt struct {
		If   token.Pos // position of "if" keyword
		Init Stmt      // initialization statement; or nil
		Cond Expr      // condition
		Body *BlockStmt
		Else Stmt // else branch; or nil
	}
A CaseClause represents a case of an expression or type switch statement.
	CaseClause struct {
		Case  token.Pos // position of "case" or "default" keyword
		List  []Expr    // list of expressions or types; nil means default case
		Colon token.Pos // position of ":"
		Body  []Stmt    // statement list; or nil
	}
A SwitchStmt node represents an expression switch statement.
	SwitchStmt struct {
		Switch token.Pos  // position of "switch" keyword
		Init   Stmt       // initialization statement; or nil
		Tag    Expr       // tag expression; or nil
		Body   *BlockStmt // CaseClauses only
	}
A TypeSwitchStmt node represents a type switch statement.
	TypeSwitchStmt struct {
		Switch token.Pos  // position of "switch" keyword
		Init   Stmt       // initialization statement; or nil
		Assign Stmt       // x := y.(type) or y.(type)
		Body   *BlockStmt // CaseClauses only
	}
A CommClause node represents a case of a select statement.
	CommClause struct {
		Case  token.Pos // position of "case" or "default" keyword
		Comm  Stmt      // send or receive statement; nil means default case
		Colon token.Pos // position of ":"
		Body  []Stmt    // statement list; or nil
	}
A SelectStmt node represents a select statement.
	SelectStmt struct {
		Select token.Pos  // position of "select" keyword
		Body   *BlockStmt // CommClauses only
	}
A ForStmt represents a for statement.
	ForStmt struct {
		For  token.Pos // position of "for" keyword
		Init Stmt      // initialization statement; or nil
		Cond Expr      // condition; or nil
		Post Stmt      // post iteration statement; or nil
		Body *BlockStmt
	}
A RangeStmt represents a for statement with a range clause.
	RangeStmt struct {
		For        token.Pos   // position of "for" keyword
		Key, Value Expr        // Key, Value may be nil
		TokPos     token.Pos   // position of Tok; invalid if Key == nil
		Tok        token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE
		X          Expr        // value to range over
		Body       *BlockStmt
	}
)
Pos and End implementations for statement nodes.

func ( *BadStmt) () token.Pos        { return .From }
func ( *DeclStmt) () token.Pos       { return .Decl.Pos() }
func ( *EmptyStmt) () token.Pos      { return .Semicolon }
func ( *LabeledStmt) () token.Pos    { return .Label.Pos() }
func ( *ExprStmt) () token.Pos       { return .X.Pos() }
func ( *SendStmt) () token.Pos       { return .Chan.Pos() }
func ( *IncDecStmt) () token.Pos     { return .X.Pos() }
func ( *AssignStmt) () token.Pos     { return .Lhs[0].Pos() }
func ( *GoStmt) () token.Pos         { return .Go }
func ( *DeferStmt) () token.Pos      { return .Defer }
func ( *ReturnStmt) () token.Pos     { return .Return }
func ( *BranchStmt) () token.Pos     { return .TokPos }
func ( *BlockStmt) () token.Pos      { return .Lbrace }
func ( *IfStmt) () token.Pos         { return .If }
func ( *CaseClause) () token.Pos     { return .Case }
func ( *SwitchStmt) () token.Pos     { return .Switch }
func ( *TypeSwitchStmt) () token.Pos { return .Switch }
func ( *CommClause) () token.Pos     { return .Case }
func ( *SelectStmt) () token.Pos     { return .Select }
func ( *ForStmt) () token.Pos        { return .For }
func ( *RangeStmt) () token.Pos      { return .For }

func ( *BadStmt) () token.Pos  { return .To }
func ( *DeclStmt) () token.Pos { return .Decl.End() }
func ( *EmptyStmt) () token.Pos {
	if .Implicit {
		return .Semicolon
	}
	return .Semicolon + 1 /* len(";") */
}
func ( *LabeledStmt) () token.Pos { return .Stmt.End() }
func ( *ExprStmt) () token.Pos    { return .X.End() }
func ( *SendStmt) () token.Pos    { return .Value.End() }
func ( *IncDecStmt) () token.Pos {
	return .TokPos + 2 /* len("++") */
}
func ( *AssignStmt) () token.Pos { return .Rhs[len(.Rhs)-1].End() }
func ( *GoStmt) () token.Pos     { return .Call.End() }
func ( *DeferStmt) () token.Pos  { return .Call.End() }
func ( *ReturnStmt) () token.Pos {
	if  := len(.Results);  > 0 {
		return .Results[-1].End()
	}
	return .Return + 6 // len("return")
}
func ( *BranchStmt) () token.Pos {
	if .Label != nil {
		return .Label.End()
	}
	return token.Pos(int(.TokPos) + len(.Tok.String()))
}
func ( *BlockStmt) () token.Pos {
	if .Rbrace.IsValid() {
		return .Rbrace + 1
	}
	if  := len(.List);  > 0 {
		return .List[-1].End()
	}
	return .Lbrace + 1
}
func ( *IfStmt) () token.Pos {
	if .Else != nil {
		return .Else.End()
	}
	return .Body.End()
}
func ( *CaseClause) () token.Pos {
	if  := len(.Body);  > 0 {
		return .Body[-1].End()
	}
	return .Colon + 1
}
func ( *SwitchStmt) () token.Pos     { return .Body.End() }
func ( *TypeSwitchStmt) () token.Pos { return .Body.End() }
func ( *CommClause) () token.Pos {
	if  := len(.Body);  > 0 {
		return .Body[-1].End()
	}
	return .Colon + 1
}
func ( *SelectStmt) () token.Pos { return .Body.End() }
func ( *ForStmt) () token.Pos    { return .Body.End() }
func ( *RangeStmt) () token.Pos  { return .Body.End() }
stmtNode() ensures that only statement nodes can be assigned to a Stmt.
func (*BadStmt) ()        {}
func (*DeclStmt) ()       {}
func (*EmptyStmt) ()      {}
func (*LabeledStmt) ()    {}
func (*ExprStmt) ()       {}
func (*SendStmt) ()       {}
func (*IncDecStmt) ()     {}
func (*AssignStmt) ()     {}
func (*GoStmt) ()         {}
func (*DeferStmt) ()      {}
func (*ReturnStmt) ()     {}
func (*BranchStmt) ()     {}
func (*BlockStmt) ()      {}
func (*IfStmt) ()         {}
func (*CaseClause) ()     {}
func (*SwitchStmt) ()     {}
func (*TypeSwitchStmt) () {}
func (*CommClause) ()     {}
func (*SelectStmt) ()     {}
func (*ForStmt) ()        {}
func (*RangeStmt) ()      {}
---------------------------------------------------------------------------- Declarations
A Spec node represents a single (non-parenthesized) import, constant, type, or variable declaration.
The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
	Spec interface {
		Node
		specNode()
	}
An ImportSpec node represents a single package import.
	ImportSpec struct {
		Doc     *CommentGroup // associated documentation; or nil
		Name    *Ident        // local package name (including "."); or nil
		Path    *BasicLit     // import path
		Comment *CommentGroup // line comments; or nil
		EndPos  token.Pos     // end of spec (overrides Path.Pos if nonzero)
	}
A ValueSpec node represents a constant or variable declaration (ConstSpec or VarSpec production).
	ValueSpec struct {
		Doc     *CommentGroup // associated documentation; or nil
		Names   []*Ident      // value names (len(Names) > 0)
		Type    Expr          // value type; or nil
		Values  []Expr        // initial values; or nil
		Comment *CommentGroup // line comments; or nil
	}
A TypeSpec node represents a type declaration (TypeSpec production).
	TypeSpec struct {
		Doc     *CommentGroup // associated documentation; or nil
		Name    *Ident        // type name
		Assign  token.Pos     // position of '=', if any
		Type    Expr          // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
		Comment *CommentGroup // line comments; or nil
	}
)
Pos and End implementations for spec nodes.

func ( *ImportSpec) () token.Pos {
	if .Name != nil {
		return .Name.Pos()
	}
	return .Path.Pos()
}
func ( *ValueSpec) () token.Pos { return .Names[0].Pos() }
func ( *TypeSpec) () token.Pos  { return .Name.Pos() }

func ( *ImportSpec) () token.Pos {
	if .EndPos != 0 {
		return .EndPos
	}
	return .Path.End()
}

func ( *ValueSpec) () token.Pos {
	if  := len(.Values);  > 0 {
		return .Values[-1].End()
	}
	if .Type != nil {
		return .Type.End()
	}
	return .Names[len(.Names)-1].End()
}
func ( *TypeSpec) () token.Pos { return .Type.End() }
specNode() ensures that only spec nodes can be assigned to a Spec.
func (*ImportSpec) () {}
func (*ValueSpec) ()  {}
func (*TypeSpec) ()   {}
A declaration is represented by one of the following declaration nodes.
A BadDecl node is a placeholder for a declaration containing syntax errors for which a correct declaration node cannot be created.
	BadDecl struct {
		From, To token.Pos // position range of bad declaration
	}
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
	GenDecl struct {
		Doc    *CommentGroup // associated documentation; or nil
		TokPos token.Pos     // position of Tok
		Tok    token.Token   // IMPORT, CONST, TYPE, VAR
		Lparen token.Pos     // position of '(', if any
		Specs  []Spec
		Rparen token.Pos // position of ')', if any
	}
A FuncDecl node represents a function declaration.
	FuncDecl struct {
		Doc  *CommentGroup // associated documentation; or nil
		Recv *FieldList    // receiver (methods); or nil (functions)
		Name *Ident        // function/method name
		Type *FuncType     // function signature: parameters, results, and position of "func" keyword
		Body *BlockStmt    // function body; or nil for external (non-Go) function
	}
)
Pos and End implementations for declaration nodes.

func ( *BadDecl) () token.Pos  { return .From }
func ( *GenDecl) () token.Pos  { return .TokPos }
func ( *FuncDecl) () token.Pos { return .Type.Pos() }

func ( *BadDecl) () token.Pos { return .To }
func ( *GenDecl) () token.Pos {
	if .Rparen.IsValid() {
		return .Rparen + 1
	}
	return .Specs[0].End()
}
func ( *FuncDecl) () token.Pos {
	if .Body != nil {
		return .Body.End()
	}
	return .Type.End()
}
declNode() ensures that only declaration nodes can be assigned to a Decl.
func (*BadDecl) ()  {}
func (*GenDecl) ()  {}
func (*FuncDecl) () {}
---------------------------------------------------------------------------- Files and packages
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).
type File struct {
	Doc        *CommentGroup   // associated documentation; or nil
	Package    token.Pos       // position of "package" keyword
	Name       *Ident          // package name
	Decls      []Decl          // top-level declarations; or nil
	Scope      *Scope          // package scope (this file only)
	Imports    []*ImportSpec   // imports in this file
	Unresolved []*Ident        // unresolved identifiers in this file
	Comments   []*CommentGroup // list of all comments in the source file
}

func ( *File) () token.Pos { return .Package }
func ( *File) () token.Pos {
	if  := len(.Decls);  > 0 {
		return .Decls[-1].End()
	}
	return .Name.End()
}
A Package node represents a set of source files collectively building a Go package.
type Package struct {
	Name    string             // package name
	Scope   *Scope             // package scope across all files
	Imports map[string]*Object // map of package id -> package object
	Files   map[string]*File   // Go source files by filename
}

func ( *Package) () token.Pos { return token.NoPos }