func (s *BlockStmt) End() token.Pos {
	if s.Rbrace.IsValid() {
		return s.Rbrace + 1
	}
	if n := len(s.List); n > 0 {
		return s.List[n-1].End()
	}
	return s.Lbrace + 1
}
End returns position of first character immediately after the node.
package ast
import (
	"go/ast"
	"strings"
	"github.com/goplus/gop/token"
)
type Node = ast.Node
type Expr interface {
	Node
	exprNode()
}
type Stmt interface {
	Node
	stmtNode()
}
type Decl interface {
	Node
	declNode()
}
type Comment struct {
	Slash token.Pos  
	Text  string     
}
func (c *Comment) Pos() token.Pos { return c.Slash }
func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) }
type CommentGroup struct {
	List []*Comment  
}
func (g *CommentGroup) Pos() token.Pos { return g.List[0].Pos() }
func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() }
func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }
func stripTrailingWhitespace(s string) string {
	i := len(s)
	for i > 0 && isWhitespace(s[i-1]) {
		i--
	}
	return s[0:i]
}
func (g *CommentGroup) Text() string {
	if g == nil {
		return ""
	}
	comments := make([]string, len(g.List))
	for i, c := range g.List {
		comments[i] = c.Text
	}
	lines := make([]string, 0, 10)  
	for _, c := range comments {
		switch c[1] {
		case '/':
			c = c[2:]
			if len(c) > 0 && c[0] == ' ' {
				c = c[1:]
			}
		case '*':
			c = c[2 : len(c)-2]
		}
		cl := strings.Split(c, "\n")
		for _, l := range cl {
			lines = append(lines, stripTrailingWhitespace(l))
		}
	}
	n := 0
	for _, line := range lines {
		if line != "" || n > 0 && lines[n-1] != "" {
			lines[n] = line
			n++
		}
	}
	lines = lines[0:n]
	if n > 0 && lines[n-1] != "" {
		lines = append(lines, "")
	}
	return strings.Join(lines, "\n")
}
type Field struct {
	Doc     *CommentGroup  
	Names   []*Ident       
	Type    Expr           
	Tag     *BasicLit      
	Comment *CommentGroup  
}
func (f *Field) Pos() token.Pos {
	if len(f.Names) > 0 {
		return f.Names[0].Pos()
	}
	return f.Type.Pos()
}
func (f *Field) End() token.Pos {
	if f.Tag != nil {
		return f.Tag.End()
	}
	return f.Type.End()
}
type FieldList struct {
	Opening token.Pos  
	List    []*Field   
	Closing token.Pos  
}
func (f *FieldList) Pos() token.Pos {
	if f.Opening.IsValid() {
		return f.Opening
	}
	if len(f.List) > 0 {
		return f.List[0].Pos()
	}
	return token.NoPos
}
func (f *FieldList) End() token.Pos {
	if f.Closing.IsValid() {
		return f.Closing + 1
	}
	if n := len(f.List); n > 0 {
		return f.List[n-1].End()
	}
	return token.NoPos
}
func (f *FieldList) NumFields() int {
	n := 0
	if f != nil {
		for _, g := range f.List {
			m := len(g.Names)
			if m == 0 {
				m = 1
			}
			n += m
		}
	}
	return n
}
type (
	BadExpr struct {
		From, To token.Pos  
	}
	Ident struct {
		NamePos token.Pos  
		Name    string     
		Obj     *Object    
	}
	Ellipsis struct {
		Ellipsis token.Pos  
		Elt      Expr       
	}
	BasicLit struct {
		ValuePos token.Pos    
		Kind     token.Token  
		Value    string       
	}
	FuncLit struct {
		Type *FuncType   
		Body *BlockStmt  
	}
	CompositeLit struct {
		Type       Expr       
		Lbrace     token.Pos  
		Elts       []Expr     
		Rbrace     token.Pos  
		Incomplete bool       
	}
	ParenExpr struct {
		Lparen token.Pos  
		X      Expr       
		Rparen token.Pos  
	}
	SelectorExpr struct {
		X   Expr    
		Sel *Ident  
	}
	IndexExpr struct {
		X      Expr       
		Lbrack token.Pos  
		Index  Expr       
		Rbrack token.Pos  
	}
	SliceExpr struct {
		X      Expr       
		Lbrack token.Pos  
		Low    Expr       
		High   Expr       
		Max    Expr       
		Slice3 bool       
		Rbrack token.Pos  
	}
	TypeAssertExpr struct {
		X      Expr       
		Lparen token.Pos  
		Type   Expr       
		Rparen token.Pos  
	}
	CallExpr struct {
		Fun        Expr       
		Lparen     token.Pos  
		Args       []Expr     
		Ellipsis   token.Pos  
		Rparen     token.Pos  
		NoParenEnd token.Pos
	}
	StarExpr struct {
		Star token.Pos  
		X    Expr       
	}
	UnaryExpr struct {
		OpPos token.Pos    
		Op    token.Token  
		X     Expr         
	}
	BinaryExpr struct {
		X     Expr         
		OpPos token.Pos    
		Op    token.Token  
		Y     Expr         
	}
	KeyValueExpr struct {
		Key   Expr
		Colon token.Pos  
		Value Expr
	}
)
type ChanDir int
const (
	SEND ChanDir = 1 << iota
	RECV
)
type (
	ArrayType struct {
		Lbrack token.Pos  
		Len    Expr       
		Elt    Expr       
	}
	StructType struct {
		Struct     token.Pos   
		Fields     *FieldList  
		Incomplete bool        
	}
	FuncType struct {
		Func    token.Pos   
		Params  *FieldList  
		Results *FieldList  
	}
	InterfaceType struct {
		Interface  token.Pos   
		Methods    *FieldList  
		Incomplete bool        
	}
	MapType struct {
		Map   token.Pos  
		Key   Expr
		Value Expr
	}
	ChanType struct {
		Begin token.Pos  
		Arrow token.Pos  
		Dir   ChanDir    
		Value Expr       
	}
)
func (x *BadExpr) Pos() token.Pos { return x.From }
func (x *Ident) Pos() token.Pos { return x.NamePos }
func (x *Ellipsis) Pos() token.Pos { return x.Ellipsis }
func (x *BasicLit) Pos() token.Pos { return x.ValuePos }
func (x *FuncLit) Pos() token.Pos { return x.Type.Pos() }
func (x *CompositeLit) Pos() token.Pos {
	if x.Type != nil {
		return x.Type.Pos()
	}
	return x.Lbrace
}
func (x *ParenExpr) Pos() token.Pos { return x.Lparen }
func (x *SelectorExpr) Pos() token.Pos { return x.X.Pos() }
func (x *IndexExpr) Pos() token.Pos { return x.X.Pos() }
func (x *SliceExpr) Pos() token.Pos { return x.X.Pos() }
func (x *TypeAssertExpr) Pos() token.Pos { return x.X.Pos() }
func (x *CallExpr) Pos() token.Pos { return x.Fun.Pos() }
func (x *StarExpr) Pos() token.Pos { return x.Star }
func (x *UnaryExpr) Pos() token.Pos { return x.OpPos }
func (x *BinaryExpr) Pos() token.Pos { return x.X.Pos() }
func (x *KeyValueExpr) Pos() token.Pos { return x.Key.Pos() }
func (x *ArrayType) Pos() token.Pos { return x.Lbrack }
func (x *StructType) Pos() token.Pos { return x.Struct }
func (x *FuncType) Pos() token.Pos {
	if x.Func.IsValid() || x.Params == nil {  
		return x.Func
	}
	return x.Params.Pos()  
}
func (x *InterfaceType) Pos() token.Pos { return x.Interface }
func (x *MapType) Pos() token.Pos { return x.Map }
func (x *ChanType) Pos() token.Pos { return x.Begin }
func (x *BadExpr) End() token.Pos { return x.To }
func (x *Ident) End() token.Pos { return token.Pos(int(x.NamePos) + len(x.Name)) }
func (x *Ellipsis) End() token.Pos {
	if x.Elt != nil {
		return x.Elt.End()
	}
	return x.Ellipsis + 3  
}
func (x *BasicLit) End() token.Pos { return token.Pos(int(x.ValuePos) + len(x.Value)) }
func (x *FuncLit) End() token.Pos { return x.Body.End() }
func (x *CompositeLit) End() token.Pos { return x.Rbrace + 1 }
func (x *ParenExpr) End() token.Pos { return x.Rparen + 1 }
func (x *SelectorExpr) End() token.Pos { return x.Sel.End() }
func (x *IndexExpr) End() token.Pos { return x.Rbrack + 1 }
func (x *SliceExpr) End() token.Pos { return x.Rbrack + 1 }
func (x *TypeAssertExpr) End() token.Pos { return x.Rparen + 1 }
func (x *CallExpr) End() token.Pos {
	if x.NoParenEnd != token.NoPos {
		return x.NoParenEnd
	}
	return x.Rparen + 1
}
func (x *StarExpr) End() token.Pos { return x.X.End() }
func (x *UnaryExpr) End() token.Pos { return x.X.End() }
func (x *BinaryExpr) End() token.Pos { return x.Y.End() }
func (x *KeyValueExpr) End() token.Pos { return x.Value.End() }
func (x *ArrayType) End() token.Pos { return x.Elt.End() }
func (x *StructType) End() token.Pos { return x.Fields.End() }
func (x *FuncType) End() token.Pos {
	if x.Results != nil {
		return x.Results.End()
	}
	return x.Params.End()
}
func (x *InterfaceType) End() token.Pos { return x.Methods.End() }
func (x *MapType) End() token.Pos { return x.Value.End() }
func (x *ChanType) End() token.Pos { return x.Value.End() }
func (*BadExpr) exprNode()        {}
func (*Ident) exprNode()          {}
func (*Ellipsis) exprNode()       {}
func (*BasicLit) exprNode()       {}
func (*FuncLit) exprNode()        {}
func (*CompositeLit) exprNode()   {}
func (*ParenExpr) exprNode()      {}
func (*SelectorExpr) exprNode()   {}
func (*IndexExpr) exprNode()      {}
func (*SliceExpr) exprNode()      {}
func (*TypeAssertExpr) exprNode() {}
func (*CallExpr) exprNode()       {}
func (*StarExpr) exprNode()       {}
func (*UnaryExpr) exprNode()      {}
func (*BinaryExpr) exprNode()     {}
func (*KeyValueExpr) exprNode()   {}
func (*ArrayType) exprNode()     {}
func (*StructType) exprNode()    {}
func (*FuncType) exprNode()      {}
func (*InterfaceType) exprNode() {}
func (*MapType) exprNode()       {}
func (*ChanType) exprNode()      {}
func NewIdent(name string) *Ident { return &Ident{token.NoPos, name, nil} }
func IsExported(name string) bool { return token.IsExported(name) }
func (x *Ident) IsExported() bool { return token.IsExported(x.Name) }
func (x *Ident) String() string {
	if x != nil {
		return x.Name
	}
	return "<nil>"
}
type (
	BadStmt struct {
		From, To token.Pos  
	}
	DeclStmt struct {
		Decl Decl  
	}
	EmptyStmt struct {
		Semicolon token.Pos  
		Implicit  bool       
	}
	LabeledStmt struct {
		Label *Ident
		Colon token.Pos  
		Stmt  Stmt
	}
	ExprStmt struct {
		X Expr  
	}
	SendStmt struct {
		Chan  Expr
		Arrow token.Pos  
		Value Expr
	}
	IncDecStmt struct {
		X      Expr
		TokPos token.Pos    
		Tok    token.Token  
	}
	AssignStmt struct {
		Lhs    []Expr       
		TokPos token.Pos    
		Tok    token.Token  
		Rhs    []Expr       
	}
	GoStmt struct {
		Go   token.Pos  
		Call *CallExpr
	}
	DeferStmt struct {
		Defer token.Pos  
		Call  *CallExpr
	}
	ReturnStmt struct {
		Return  token.Pos  
		Results []Expr     
	}
	BranchStmt struct {
		TokPos token.Pos    
		Tok    token.Token  
		Label  *Ident       
	}
	BlockStmt struct {
		Lbrace token.Pos  
		List   []Stmt
		Rbrace token.Pos  
	}
	IfStmt struct {
		If   token.Pos  
		Init Stmt       
		Cond Expr       
		Body *BlockStmt
		Else Stmt  
	}
	CaseClause struct {
		Case  token.Pos  
		List  []Expr     
		Colon token.Pos  
		Body  []Stmt     
	}
	SwitchStmt struct {
		Switch token.Pos   
		Init   Stmt        
		Tag    Expr        
		Body   *BlockStmt  
	}
	TypeSwitchStmt struct {
		Switch token.Pos   
		Init   Stmt        
		Assign Stmt        
		Body   *BlockStmt  
	}
	CommClause struct {
		Case  token.Pos  
		Comm  Stmt       
		Colon token.Pos  
		Body  []Stmt     
	}
	SelectStmt struct {
		Select token.Pos   
		Body   *BlockStmt  
	}
	ForStmt struct {
		For  token.Pos  
		Init Stmt       
		Cond Expr       
		Post Stmt       
		Body *BlockStmt
	}
	RangeStmt struct {
		For        token.Pos    
		Key, Value Expr         
		TokPos     token.Pos    
		Tok        token.Token  
		X          Expr         
		Body       *BlockStmt
	}
)
func (s *BadStmt) Pos() token.Pos { return s.From }
func (s *DeclStmt) Pos() token.Pos { return s.Decl.Pos() }
func (s *EmptyStmt) Pos() token.Pos { return s.Semicolon }
func (s *LabeledStmt) Pos() token.Pos { return s.Label.Pos() }
func (s *ExprStmt) Pos() token.Pos { return s.X.Pos() }
func (s *SendStmt) Pos() token.Pos { return s.Chan.Pos() }
func (s *IncDecStmt) Pos() token.Pos { return s.X.Pos() }
func (s *AssignStmt) Pos() token.Pos { return s.Lhs[0].Pos() }
func (s *GoStmt) Pos() token.Pos { return s.Go }
func (s *DeferStmt) Pos() token.Pos { return s.Defer }
func (s *ReturnStmt) Pos() token.Pos { return s.Return }
func (s *BranchStmt) Pos() token.Pos { return s.TokPos }
func (s *BlockStmt) Pos() token.Pos { return s.Lbrace }
func (s *IfStmt) Pos() token.Pos { return s.If }
func (s *CaseClause) Pos() token.Pos { return s.Case }
func (s *SwitchStmt) Pos() token.Pos { return s.Switch }
func (s *TypeSwitchStmt) Pos() token.Pos { return s.Switch }
func (s *CommClause) Pos() token.Pos { return s.Case }
func (s *SelectStmt) Pos() token.Pos { return s.Select }
func (s *ForStmt) Pos() token.Pos { return s.For }
func (s *RangeStmt) Pos() token.Pos { return s.For }
func (s *BadStmt) End() token.Pos { return s.To }
func (s *DeclStmt) End() token.Pos { return s.Decl.End() }
func (s *EmptyStmt) End() token.Pos {
	if s.Implicit {
		return s.Semicolon
	}
	return s.Semicolon + 1  
}
func (s *LabeledStmt) End() token.Pos { return s.Stmt.End() }
func (s *ExprStmt) End() token.Pos { return s.X.End() }
func (s *SendStmt) End() token.Pos { return s.Value.End() }
func (s *IncDecStmt) End() token.Pos {
	return s.TokPos + 2  
}
func (s *AssignStmt) End() token.Pos { return s.Rhs[len(s.Rhs)-1].End() }
func (s *GoStmt) End() token.Pos { return s.Call.End() }
func (s *DeferStmt) End() token.Pos { return s.Call.End() }
func (s *ReturnStmt) End() token.Pos {
	if n := len(s.Results); n > 0 {
		return s.Results[n-1].End()
	}
	return s.Return + 6  
}
func (s *BranchStmt) End() token.Pos {
	if s.Label != nil {
		return s.Label.End()
	}
	return token.Pos(int(s.TokPos) + len(s.Tok.String()))
}