1// Copyright 2009 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Package ast declares the types used to represent syntax trees for Go 6// packages. 7// 8package ast 9 10import ( 11 "go/token" 12 "strings" 13) 14 15// ---------------------------------------------------------------------------- 16// Interfaces 17// 18// There are 3 main classes of nodes: Expressions and type nodes, 19// statement nodes, and declaration nodes. The node names usually 20// match the corresponding Go spec production names to which they 21// correspond. The node fields correspond to the individual parts 22// of the respective productions. 23// 24// All nodes contain position information marking the beginning of 25// the corresponding source text segment; it is accessible via the 26// Pos accessor method. Nodes may contain additional position info 27// for language constructs where comments may be found between parts 28// of the construct (typically any larger, parenthesized subpart). 29// That position information is needed to properly position comments 30// when printing the construct. 31 32// All node types implement the Node interface. 33type Node interface { 34 Pos() token.Pos // position of first character belonging to the node 35 End() token.Pos // position of first character immediately after the node 36} 37 38// All expression nodes implement the Expr interface. 39type Expr interface { 40 Node 41 exprNode() 42} 43 44// All statement nodes implement the Stmt interface. 45type Stmt interface { 46 Node 47 stmtNode() 48} 49 50// All declaration nodes implement the Decl interface. 51type Decl interface { 52 Node 53 declNode() 54} 55 56// ---------------------------------------------------------------------------- 57// Comments 58 59// A Comment node represents a single //-style or /*-style comment. 60type Comment struct { 61 Slash token.Pos // position of "/" starting the comment 62 Text string // comment text (excluding '\n' for //-style comments) 63} 64 65func (c *Comment) Pos() token.Pos { return c.Slash } 66func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) } 67 68// A CommentGroup represents a sequence of comments 69// with no other tokens and no empty lines between. 70// 71type CommentGroup struct { 72 List []*Comment // len(List) > 0 73} 74 75func (g *CommentGroup) Pos() token.Pos { return g.List[0].Pos() } 76func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() } 77 78func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' } 79 80func stripTrailingWhitespace(s string) string { 81 i := len(s) 82 for i > 0 && isWhitespace(s[i-1]) { 83 i-- 84 } 85 return s[0:i] 86} 87 88// Text returns the text of the comment. 89// Comment markers (//, /*, and */), the first space of a line comment, and 90// leading and trailing empty lines are removed. Multiple empty lines are 91// reduced to one, and trailing space on lines is trimmed. Unless the result 92// is empty, it is newline-terminated. 93// 94func (g *CommentGroup) Text() string { 95 if g == nil { 96 return "" 97 } 98 comments := make([]string, len(g.List)) 99 for i, c := range g.List { 100 comments[i] = c.Text 101 } 102 103 lines := make([]string, 0, 10) // most comments are less than 10 lines 104 for _, c := range comments { 105 // Remove comment markers. 106 // The parser has given us exactly the comment text. 107 switch c[1] { 108 case '/': 109 //-style comment (no newline at the end) 110 c = c[2:] 111 // strip first space - required for Example tests 112 if len(c) > 0 && c[0] == ' ' { 113 c = c[1:] 114 } 115 case '*': 116 /*-style comment */ 117 c = c[2 : len(c)-2] 118 } 119 120 // Split on newlines. 121 cl := strings.Split(c, "\n") 122 123 // Walk lines, stripping trailing white space and adding to list. 124 for _, l := range cl { 125 lines = append(lines, stripTrailingWhitespace(l)) 126 } 127 } 128 129 // Remove leading blank lines; convert runs of 130 // interior blank lines to a single blank line. 131 n := 0 132 for _, line := range lines { 133 if line != "" || n > 0 && lines[n-1] != "" { 134 lines[n] = line 135 n++ 136 } 137 } 138 lines = lines[0:n] 139 140 // Add final "" entry to get trailing newline from Join. 141 if n > 0 && lines[n-1] != "" { 142 lines = append(lines, "") 143 } 144 145 return strings.Join(lines, "\n") 146} 147 148// ---------------------------------------------------------------------------- 149// Expressions and types 150 151// A Field represents a Field declaration list in a struct type, 152// a method list in an interface type, or a parameter/result declaration 153// in a signature. 154// Field.Names is nil for unnamed parameters (parameter lists which only contain types) 155// and embedded struct fields. In the latter case, the field name is the type name. 156// 157type Field struct { 158 Doc *CommentGroup // associated documentation; or nil 159 Names []*Ident // field/method/parameter names; or nil 160 Type Expr // field/method/parameter type 161 Tag *BasicLit // field tag; or nil 162 Comment *CommentGroup // line comments; or nil 163} 164 165func (f *Field) Pos() token.Pos { 166 if len(f.Names) > 0 { 167 return f.Names[0].Pos() 168 } 169 return f.Type.Pos() 170} 171 172func (f *Field) End() token.Pos { 173 if f.Tag != nil { 174 return f.Tag.End() 175 } 176 return f.Type.End() 177} 178 179// A FieldList represents a list of Fields, enclosed by parentheses or braces. 180type FieldList struct { 181 Opening token.Pos // position of opening parenthesis/brace, if any 182 List []*Field // field list; or nil 183 Closing token.Pos // position of closing parenthesis/brace, if any 184} 185 186func (f *FieldList) Pos() token.Pos { 187 if f.Opening.IsValid() { 188 return f.Opening 189 } 190 // the list should not be empty in this case; 191 // be conservative and guard against bad ASTs 192 if len(f.List) > 0 { 193 return f.List[0].Pos() 194 } 195 return token.NoPos 196} 197 198func (f *FieldList) End() token.Pos { 199 if f.Closing.IsValid() { 200 return f.Closing + 1 201 } 202 // the list should not be empty in this case; 203 // be conservative and guard against bad ASTs 204 if n := len(f.List); n > 0 { 205 return f.List[n-1].End() 206 } 207 return token.NoPos 208} 209 210// NumFields returns the number of parameters or struct fields represented by a FieldList. 211func (f *FieldList) NumFields() int { 212 n := 0 213 if f != nil { 214 for _, g := range f.List { 215 m := len(g.Names) 216 if m == 0 { 217 m = 1 218 } 219 n += m 220 } 221 } 222 return n 223} 224 225// An expression is represented by a tree consisting of one 226// or more of the following concrete expression nodes. 227// 228type ( 229 // A BadExpr node is a placeholder for expressions containing 230 // syntax errors for which no correct expression nodes can be 231 // created. 232 // 233 BadExpr struct { 234 From, To token.Pos // position range of bad expression 235 } 236 237 // An Ident node represents an identifier. 238 Ident struct { 239 NamePos token.Pos // identifier position 240 Name string // identifier name 241 Obj *Object // denoted object; or nil 242 } 243 244 // An Ellipsis node stands for the "..." type in a 245 // parameter list or the "..." length in an array type. 246 // 247 Ellipsis struct { 248 Ellipsis token.Pos // position of "..." 249 Elt Expr // ellipsis element type (parameter lists only); or nil 250 } 251 252 // A BasicLit node represents a literal of basic type. 253 BasicLit struct { 254 ValuePos token.Pos // literal position 255 Kind token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING 256 Value string // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o` 257 } 258 259 // A FuncLit node represents a function literal. 260 FuncLit struct { 261 Type *FuncType // function type 262 Body *BlockStmt // function body 263 } 264 265 // A CompositeLit node represents a composite literal. 266 CompositeLit struct { 267 Type Expr // literal type; or nil 268 Lbrace token.Pos // position of "{" 269 Elts []Expr // list of composite elements; or nil 270 Rbrace token.Pos // position of "}" 271 Incomplete bool // true if (source) expressions are missing in the Elts list 272 } 273 274 // A ParenExpr node represents a parenthesized expression. 275 ParenExpr struct { 276 Lparen token.Pos // position of "(" 277 X Expr // parenthesized expression 278 Rparen token.Pos // position of ")" 279 } 280 281 // A SelectorExpr node represents an expression followed by a selector. 282 SelectorExpr struct { 283 X Expr // expression 284 Sel *Ident // field selector 285 } 286 287 // An IndexExpr node represents an expression followed by an index. 288 IndexExpr struct { 289 X Expr // expression 290 Lbrack token.Pos // position of "[" 291 Index Expr // index expression 292 Rbrack token.Pos // position of "]" 293 } 294 295 // A SliceExpr node represents an expression followed by slice indices. 296 SliceExpr struct { 297 X Expr // expression 298 Lbrack token.Pos // position of "[" 299 Low Expr // begin of slice range; or nil 300 High Expr // end of slice range; or nil 301 Max Expr // maximum capacity of slice; or nil 302 Slice3 bool // true if 3-index slice (2 colons present) 303 Rbrack token.Pos // position of "]" 304 } 305 306 // A TypeAssertExpr node represents an expression followed by a 307 // type assertion. 308 // 309 TypeAssertExpr struct { 310 X Expr // expression 311 Lparen token.Pos // position of "(" 312 Type Expr // asserted type; nil means type switch X.(type) 313 Rparen token.Pos // position of ")" 314 } 315 316 // A CallExpr node represents an expression followed by an argument list. 317 CallExpr struct { 318 Fun Expr // function expression 319 Lparen token.Pos // position of "(" 320 Args []Expr // function arguments; or nil 321 Ellipsis token.Pos // position of "..." (token.NoPos if there is no "...") 322 Rparen token.Pos // position of ")" 323 } 324 325 // A StarExpr node represents an expression of the form "*" Expression. 326 // Semantically it could be a unary "*" expression, or a pointer type. 327 // 328 StarExpr struct { 329 Star token.Pos // position of "*" 330 X Expr // operand 331 } 332 333 // A UnaryExpr node represents a unary expression. 334 // Unary "*" expressions are represented via StarExpr nodes. 335 // 336 UnaryExpr struct { 337 OpPos token.Pos // position of Op 338 Op token.Token // operator 339 X Expr // operand 340 } 341 342 // A BinaryExpr node represents a binary expression. 343 BinaryExpr struct { 344 X Expr // left operand 345 OpPos token.Pos // position of Op 346 Op token.Token // operator 347 Y Expr // right operand 348 } 349 350 // A KeyValueExpr node represents (key : value) pairs 351 // in composite literals. 352 // 353 KeyValueExpr struct { 354 Key Expr 355 Colon token.Pos // position of ":" 356 Value Expr 357 } 358) 359 360// The direction of a channel type is indicated by a bit 361// mask including one or both of the following constants. 362// 363type ChanDir int 364 365const ( 366 SEND ChanDir = 1 << iota 367 RECV 368) 369 370// A type is represented by a tree consisting of one 371// or more of the following type-specific expression 372// nodes. 373// 374type ( 375 // An ArrayType node represents an array or slice type. 376 ArrayType struct { 377 Lbrack token.Pos // position of "[" 378 Len Expr // Ellipsis node for [...]T array types, nil for slice types 379 Elt Expr // element type 380 } 381 382 // A StructType node represents a struct type. 383 StructType struct { 384 Struct token.Pos // position of "struct" keyword 385 Fields *FieldList // list of field declarations 386 Incomplete bool // true if (source) fields are missing in the Fields list 387 } 388 389 // Pointer types are represented via StarExpr nodes. 390 391 // A FuncType node represents a function type. 392 FuncType struct { 393 Func token.Pos // position of "func" keyword (token.NoPos if there is no "func") 394 Params *FieldList // (incoming) parameters; non-nil 395 Results *FieldList // (outgoing) results; or nil 396 } 397 398 // An InterfaceType node represents an interface type. 399 InterfaceType struct { 400 Interface token.Pos // position of "interface" keyword 401 Methods *FieldList // list of methods 402 Incomplete bool // true if (source) methods are missing in the Methods list 403 } 404 405 // A MapType node represents a map type. 406 MapType struct { 407 Map token.Pos // position of "map" keyword 408 Key Expr 409 Value Expr 410 } 411 412 // A ChanType node represents a channel type. 413 ChanType struct { 414 Begin token.Pos // position of "chan" keyword or "<-" (whichever comes first) 415 Arrow token.Pos // position of "<-" (token.NoPos if there is no "<-") 416 Dir ChanDir // channel direction 417 Value Expr // value type 418 } 419) 420 421// Pos and End implementations for expression/type nodes. 422 423func (x *BadExpr) Pos() token.Pos { return x.From } 424func (x *Ident) Pos() token.Pos { return x.NamePos } 425func (x *Ellipsis) Pos() token.Pos { return x.Ellipsis } 426func (x *BasicLit) Pos() token.Pos { return x.ValuePos } 427func (x *FuncLit) Pos() token.Pos { return x.Type.Pos() } 428func (x *CompositeLit) Pos() token.Pos { 429 if x.Type != nil { 430 return x.Type.Pos() 431 } 432 return x.Lbrace 433} 434func (x *ParenExpr) Pos() token.Pos { return x.Lparen } 435func (x *SelectorExpr) Pos() token.Pos { return x.X.Pos() } 436func (x *IndexExpr) Pos() token.Pos { return x.X.Pos() } 437func (x *SliceExpr) Pos() token.Pos { return x.X.Pos() } 438func (x *TypeAssertExpr) Pos() token.Pos { return x.X.Pos() } 439func (x *CallExpr) Pos() token.Pos { return x.Fun.Pos() } 440func (x *StarExpr) Pos() token.Pos { return x.Star } 441func (x *UnaryExpr) Pos() token.Pos { return x.OpPos } 442func (x *BinaryExpr) Pos() token.Pos { return x.X.Pos() } 443func (x *KeyValueExpr) Pos() token.Pos { return x.Key.Pos() } 444func (x *ArrayType) Pos() token.Pos { return x.Lbrack } 445func (x *StructType) Pos() token.Pos { return x.Struct } 446func (x *FuncType) Pos() token.Pos { 447 if x.Func.IsValid() || x.Params == nil { // see issue 3870 448 return x.Func 449 } 450 return x.Params.Pos() // interface method declarations have no "func" keyword 451} 452func (x *InterfaceType) Pos() token.Pos { return x.Interface } 453func (x *MapType) Pos() token.Pos { return x.Map } 454func (x *ChanType) Pos() token.Pos { return x.Begin } 455 456func (x *BadExpr) End() token.Pos { return x.To } 457func (x *Ident) End() token.Pos { return token.Pos(int(x.NamePos) + len(x.Name)) } 458func (x *Ellipsis) End() token.Pos { 459 if x.Elt != nil { 460 return x.Elt.End() 461 } 462 return x.Ellipsis + 3 // len("...") 463} 464func (x *BasicLit) End() token.Pos { return token.Pos(int(x.ValuePos) + len(x.Value)) } 465func (x *FuncLit) End() token.Pos { return x.Body.End() } 466func (x *CompositeLit) End() token.Pos { return x.Rbrace + 1 } 467func (x *ParenExpr) End() token.Pos { return x.Rparen + 1 } 468func (x *SelectorExpr) End() token.Pos { return x.Sel.End() } 469func (x *IndexExpr) End() token.Pos { return x.Rbrack + 1 } 470func (x *SliceExpr) End() token.Pos { return x.Rbrack + 1 } 471func (x *TypeAssertExpr) End() token.Pos { return x.Rparen + 1 } 472func (x *CallExpr) End() token.Pos { return x.Rparen + 1 } 473func (x *StarExpr) End() token.Pos { return x.X.End() } 474func (x *UnaryExpr) End() token.Pos { return x.X.End() } 475func (x *BinaryExpr) End() token.Pos { return x.Y.End() } 476func (x *KeyValueExpr) End() token.Pos { return x.Value.End() } 477func (x *ArrayType) End() token.Pos { return x.Elt.End() } 478func (x *StructType) End() token.Pos { return x.Fields.End() } 479func (x *FuncType) End() token.Pos { 480 if x.Results != nil { 481 return x.Results.End() 482 } 483 return x.Params.End() 484} 485func (x *InterfaceType) End() token.Pos { return x.Methods.End() } 486func (x *MapType) End() token.Pos { return x.Value.End() } 487func (x *ChanType) End() token.Pos { return x.Value.End() } 488 489// exprNode() ensures that only expression/type nodes can be 490// assigned to an Expr. 491// 492func (*BadExpr) exprNode() {} 493func (*Ident) exprNode() {} 494func (*Ellipsis) exprNode() {} 495func (*BasicLit) exprNode() {} 496func (*FuncLit) exprNode() {} 497func (*CompositeLit) exprNode() {} 498func (*ParenExpr) exprNode() {} 499func (*SelectorExpr) exprNode() {} 500func (*IndexExpr) exprNode() {} 501func (*SliceExpr) exprNode() {} 502func (*TypeAssertExpr) exprNode() {} 503func (*CallExpr) exprNode() {} 504func (*StarExpr) exprNode() {} 505func (*UnaryExpr) exprNode() {} 506func (*BinaryExpr) exprNode() {} 507func (*KeyValueExpr) exprNode() {} 508 509func (*ArrayType) exprNode() {} 510func (*StructType) exprNode() {} 511func (*FuncType) exprNode() {} 512func (*InterfaceType) exprNode() {} 513func (*MapType) exprNode() {} 514func (*ChanType) exprNode() {} 515 516// ---------------------------------------------------------------------------- 517// Convenience functions for Idents 518 519// NewIdent creates a new Ident without position. 520// Useful for ASTs generated by code other than the Go parser. 521// 522func NewIdent(name string) *Ident { return &Ident{token.NoPos, name, nil} } 523 524// IsExported reports whether name starts with an upper-case letter. 525// 526func IsExported(name string) bool { return token.IsExported(name) } 527 528// IsExported reports whether id starts with an upper-case letter. 529// 530func (id *Ident) IsExported() bool { return token.IsExported(id.Name) } 531 532func (id *Ident) String() string { 533 if id != nil { 534 return id.Name 535 } 536 return "<nil>" 537} 538 539// ---------------------------------------------------------------------------- 540// Statements 541 542// A statement is represented by a tree consisting of one 543// or more of the following concrete statement nodes. 544// 545type ( 546 // A BadStmt node is a placeholder for statements containing 547 // syntax errors for which no correct statement nodes can be 548 // created. 549 // 550 BadStmt struct { 551 From, To token.Pos // position range of bad statement 552 } 553 554 // A DeclStmt node represents a declaration in a statement list. 555 DeclStmt struct { 556 Decl Decl // *GenDecl with CONST, TYPE, or VAR token 557 } 558 559 // An EmptyStmt node represents an empty statement. 560 // The "position" of the empty statement is the position 561 // of the immediately following (explicit or implicit) semicolon. 562 // 563 EmptyStmt struct { 564 Semicolon token.Pos // position of following ";" 565 Implicit bool // if set, ";" was omitted in the source 566 } 567 568 // A LabeledStmt node represents a labeled statement. 569 LabeledStmt struct { 570 Label *Ident 571 Colon token.Pos // position of ":" 572 Stmt Stmt 573 } 574 575 // An ExprStmt node represents a (stand-alone) expression 576 // in a statement list. 577 // 578 ExprStmt struct { 579 X Expr // expression 580 } 581 582 // A SendStmt node represents a send statement. 583 SendStmt struct { 584 Chan Expr 585 Arrow token.Pos // position of "<-" 586 Value Expr 587 } 588 589 // An IncDecStmt node represents an increment or decrement statement. 590 IncDecStmt struct { 591 X Expr 592 TokPos token.Pos // position of Tok 593 Tok token.Token // INC or DEC 594 } 595 596 // An AssignStmt node represents an assignment or 597 // a short variable declaration. 598 // 599 AssignStmt struct { 600 Lhs []Expr 601 TokPos token.Pos // position of Tok 602 Tok token.Token // assignment token, DEFINE 603 Rhs []Expr 604 } 605 606 // A GoStmt node represents a go statement. 607 GoStmt struct { 608 Go token.Pos // position of "go" keyword 609 Call *CallExpr 610 } 611 612 // A DeferStmt node represents a defer statement. 613 DeferStmt struct { 614 Defer token.Pos // position of "defer" keyword 615 Call *CallExpr 616 } 617 618 // A ReturnStmt node represents a return statement. 619 ReturnStmt struct { 620 Return token.Pos // position of "return" keyword 621 Results []Expr // result expressions; or nil 622 } 623 624 // A BranchStmt node represents a break, continue, goto, 625 // or fallthrough statement. 626 // 627 BranchStmt struct { 628 TokPos token.Pos // position of Tok 629 Tok token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH) 630 Label *Ident // label name; or nil 631 } 632 633 // A BlockStmt node represents a braced statement list. 634 BlockStmt struct { 635 Lbrace token.Pos // position of "{" 636 List []Stmt 637 Rbrace token.Pos // position of "}", if any (may be absent due to syntax error) 638 } 639 640 // An IfStmt node represents an if statement. 641 IfStmt struct { 642 If token.Pos // position of "if" keyword 643 Init Stmt // initialization statement; or nil 644 Cond Expr // condition 645 Body *BlockStmt 646 Else Stmt // else branch; or nil 647 } 648 649 // A CaseClause represents a case of an expression or type switch statement. 650 CaseClause struct { 651 Case token.Pos // position of "case" or "default" keyword 652 List []Expr // list of expressions or types; nil means default case 653 Colon token.Pos // position of ":" 654 Body []Stmt // statement list; or nil 655 } 656 657 // A SwitchStmt node represents an expression switch statement. 658 SwitchStmt struct { 659 Switch token.Pos // position of "switch" keyword 660 Init Stmt // initialization statement; or nil 661 Tag Expr // tag expression; or nil 662 Body *BlockStmt // CaseClauses only 663 } 664 665 // A TypeSwitchStmt node represents a type switch statement. 666 TypeSwitchStmt struct { 667 Switch token.Pos // position of "switch" keyword 668 Init Stmt // initialization statement; or nil 669 Assign Stmt // x := y.(type) or y.(type) 670 Body *BlockStmt // CaseClauses only 671 } 672 673 // A CommClause node represents a case of a select statement. 674 CommClause struct { 675 Case token.Pos // position of "case" or "default" keyword 676 Comm Stmt // send or receive statement; nil means default case 677 Colon token.Pos // position of ":" 678 Body []Stmt // statement list; or nil 679 } 680 681 // A SelectStmt node represents a select statement. 682 SelectStmt struct { 683 Select token.Pos // position of "select" keyword 684 Body *BlockStmt // CommClauses only 685 } 686 687 // A ForStmt represents a for statement. 688 ForStmt struct { 689 For token.Pos // position of "for" keyword 690 Init Stmt // initialization statement; or nil 691 Cond Expr // condition; or nil 692 Post Stmt // post iteration statement; or nil 693 Body *BlockStmt 694 } 695 696 // A RangeStmt represents a for statement with a range clause. 697 RangeStmt struct { 698 For token.Pos // position of "for" keyword 699 Key, Value Expr // Key, Value may be nil 700 TokPos token.Pos // position of Tok; invalid if Key == nil 701 Tok token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE 702 X Expr // value to range over 703 Body *BlockStmt 704 } 705) 706 707// Pos and End implementations for statement nodes. 708 709func (s *BadStmt) Pos() token.Pos { return s.From } 710func (s *DeclStmt) Pos() token.Pos { return s.Decl.Pos() } 711func (s *EmptyStmt) Pos() token.Pos { return s.Semicolon } 712func (s *LabeledStmt) Pos() token.Pos { return s.Label.Pos() } 713func (s *ExprStmt) Pos() token.Pos { return s.X.Pos() } 714func (s *SendStmt) Pos() token.Pos { return s.Chan.Pos() } 715func (s *IncDecStmt) Pos() token.Pos { return s.X.Pos() } 716func (s *AssignStmt) Pos() token.Pos { return s.Lhs[0].Pos() } 717func (s *GoStmt) Pos() token.Pos { return s.Go } 718func (s *DeferStmt) Pos() token.Pos { return s.Defer } 719func (s *ReturnStmt) Pos() token.Pos { return s.Return } 720func (s *BranchStmt) Pos() token.Pos { return s.TokPos } 721func (s *BlockStmt) Pos() token.Pos { return s.Lbrace } 722func (s *IfStmt) Pos() token.Pos { return s.If } 723func (s *CaseClause) Pos() token.Pos { return s.Case } 724func (s *SwitchStmt) Pos() token.Pos { return s.Switch } 725func (s *TypeSwitchStmt) Pos() token.Pos { return s.Switch } 726func (s *CommClause) Pos() token.Pos { return s.Case } 727func (s *SelectStmt) Pos() token.Pos { return s.Select } 728func (s *ForStmt) Pos() token.Pos { return s.For } 729func (s *RangeStmt) Pos() token.Pos { return s.For } 730 731func (s *BadStmt) End() token.Pos { return s.To } 732func (s *DeclStmt) End() token.Pos { return s.Decl.End() } 733func (s *EmptyStmt) End() token.Pos { 734 if s.Implicit { 735 return s.Semicolon 736 } 737 return s.Semicolon + 1 /* len(";") */ 738} 739func (s *LabeledStmt) End() token.Pos { return s.Stmt.End() } 740func (s *ExprStmt) End() token.Pos { return s.X.End() } 741func (s *SendStmt) End() token.Pos { return s.Value.End() } 742func (s *IncDecStmt) End() token.Pos { 743 return s.TokPos + 2 /* len("++") */ 744} 745func (s *AssignStmt) End() token.Pos { return s.Rhs[len(s.Rhs)-1].End() } 746func (s *GoStmt) End() token.Pos { return s.Call.End() } 747func (s *DeferStmt) End() token.Pos { return s.Call.End() } 748func (s *ReturnStmt) End() token.Pos { 749 if n := len(s.Results); n > 0 { 750 return s.Results[n-1].End() 751 } 752 return s.Return + 6 // len("return") 753} 754func (s *BranchStmt) End() token.Pos { 755 if s.Label != nil { 756 return s.Label.End() 757 } 758 return token.Pos(int(s.TokPos) + len(s.Tok.String())) 759} 760func (s *BlockStmt) End() token.Pos { 761 if s.Rbrace.IsValid() { 762 return s.Rbrace + 1 763 } 764 if n := len(s.List); n > 0 { 765 return s.List[n-1].End() 766 } 767 return s.Lbrace + 1 768} 769func (s *IfStmt) End() token.Pos { 770 if s.Else != nil { 771 return s.Else.End() 772 } 773 return s.Body.End() 774} 775func (s *CaseClause) End() token.Pos { 776 if n := len(s.Body); n > 0 { 777 return s.Body[n-1].End() 778 } 779 return s.Colon + 1 780} 781func (s *SwitchStmt) End() token.Pos { return s.Body.End() } 782func (s *TypeSwitchStmt) End() token.Pos { return s.Body.End() } 783func (s *CommClause) End() token.Pos { 784 if n := len(s.Body); n > 0 { 785 return s.Body[n-1].End() 786 } 787 return s.Colon + 1 788} 789func (s *SelectStmt) End() token.Pos { return s.Body.End() } 790func (s *ForStmt) End() token.Pos { return s.Body.End() } 791func (s *RangeStmt) End() token.Pos { return s.Body.End() } 792 793// stmtNode() ensures that only statement nodes can be 794// assigned to a Stmt. 795// 796func (*BadStmt) stmtNode() {} 797func (*DeclStmt) stmtNode() {} 798func (*EmptyStmt) stmtNode() {} 799func (*LabeledStmt) stmtNode() {} 800func (*ExprStmt) stmtNode() {} 801func (*SendStmt) stmtNode() {} 802func (*IncDecStmt) stmtNode() {} 803func (*AssignStmt) stmtNode() {} 804func (*GoStmt) stmtNode() {} 805func (*DeferStmt) stmtNode() {} 806func (*ReturnStmt) stmtNode() {} 807func (*BranchStmt) stmtNode() {} 808func (*BlockStmt) stmtNode() {} 809func (*IfStmt) stmtNode() {} 810func (*CaseClause) stmtNode() {} 811func (*SwitchStmt) stmtNode() {} 812func (*TypeSwitchStmt) stmtNode() {} 813func (*CommClause) stmtNode() {} 814func (*SelectStmt) stmtNode() {} 815func (*ForStmt) stmtNode() {} 816func (*RangeStmt) stmtNode() {} 817 818// ---------------------------------------------------------------------------- 819// Declarations 820 821// A Spec node represents a single (non-parenthesized) import, 822// constant, type, or variable declaration. 823// 824type ( 825 // The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec. 826 Spec interface { 827 Node 828 specNode() 829 } 830 831 // An ImportSpec node represents a single package import. 832 ImportSpec struct { 833 Doc *CommentGroup // associated documentation; or nil 834 Name *Ident // local package name (including "."); or nil 835 Path *BasicLit // import path 836 Comment *CommentGroup // line comments; or nil 837 EndPos token.Pos // end of spec (overrides Path.Pos if nonzero) 838 } 839 840 // A ValueSpec node represents a constant or variable declaration 841 // (ConstSpec or VarSpec production). 842 // 843 ValueSpec struct { 844 Doc *CommentGroup // associated documentation; or nil 845 Names []*Ident // value names (len(Names) > 0) 846 Type Expr // value type; or nil 847 Values []Expr // initial values; or nil 848 Comment *CommentGroup // line comments; or nil 849 } 850 851 // A TypeSpec node represents a type declaration (TypeSpec production). 852 TypeSpec struct { 853 Doc *CommentGroup // associated documentation; or nil 854 Name *Ident // type name 855 Assign token.Pos // position of '=', if any 856 Type Expr // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes 857 Comment *CommentGroup // line comments; or nil 858 } 859) 860 861// Pos and End implementations for spec nodes. 862 863func (s *ImportSpec) Pos() token.Pos { 864 if s.Name != nil { 865 return s.Name.Pos() 866 } 867 return s.Path.Pos() 868} 869func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() } 870func (s *TypeSpec) Pos() token.Pos { return s.Name.Pos() } 871 872func (s *ImportSpec) End() token.Pos { 873 if s.EndPos != 0 { 874 return s.EndPos 875 } 876 return s.Path.End() 877} 878 879func (s *ValueSpec) End() token.Pos { 880 if n := len(s.Values); n > 0 { 881 return s.Values[n-1].End() 882 } 883 if s.Type != nil { 884 return s.Type.End() 885 } 886 return s.Names[len(s.Names)-1].End() 887} 888func (s *TypeSpec) End() token.Pos { return s.Type.End() } 889 890// specNode() ensures that only spec nodes can be 891// assigned to a Spec. 892// 893func (*ImportSpec) specNode() {} 894func (*ValueSpec) specNode() {} 895func (*TypeSpec) specNode() {} 896 897// A declaration is represented by one of the following declaration nodes. 898// 899type ( 900 // A BadDecl node is a placeholder for declarations containing 901 // syntax errors for which no correct declaration nodes can be 902 // created. 903 // 904 BadDecl struct { 905 From, To token.Pos // position range of bad declaration 906 } 907 908 // A GenDecl node (generic declaration node) represents an import, 909 // constant, type or variable declaration. A valid Lparen position 910 // (Lparen.IsValid()) indicates a parenthesized declaration. 911 // 912 // Relationship between Tok value and Specs element type: 913 // 914 // token.IMPORT *ImportSpec 915 // token.CONST *ValueSpec 916 // token.TYPE *TypeSpec 917 // token.VAR *ValueSpec 918 // 919 GenDecl struct { 920 Doc *CommentGroup // associated documentation; or nil 921 TokPos token.Pos // position of Tok 922 Tok token.Token // IMPORT, CONST, TYPE, VAR 923 Lparen token.Pos // position of '(', if any 924 Specs []Spec 925 Rparen token.Pos // position of ')', if any 926 } 927 928 // A FuncDecl node represents a function declaration. 929 FuncDecl struct { 930 Doc *CommentGroup // associated documentation; or nil 931 Recv *FieldList // receiver (methods); or nil (functions) 932 Name *Ident // function/method name 933 Type *FuncType // function signature: parameters, results, and position of "func" keyword 934 Body *BlockStmt // function body; or nil for external (non-Go) function 935 } 936) 937 938// Pos and End implementations for declaration nodes. 939 940func (d *BadDecl) Pos() token.Pos { return d.From } 941func (d *GenDecl) Pos() token.Pos { return d.TokPos } 942func (d *FuncDecl) Pos() token.Pos { return d.Type.Pos() } 943 944func (d *BadDecl) End() token.Pos { return d.To } 945func (d *GenDecl) End() token.Pos { 946 if d.Rparen.IsValid() { 947 return d.Rparen + 1 948 } 949 return d.Specs[0].End() 950} 951func (d *FuncDecl) End() token.Pos { 952 if d.Body != nil { 953 return d.Body.End() 954 } 955 return d.Type.End() 956} 957 958// declNode() ensures that only declaration nodes can be 959// assigned to a Decl. 960// 961func (*BadDecl) declNode() {} 962func (*GenDecl) declNode() {} 963func (*FuncDecl) declNode() {} 964 965// ---------------------------------------------------------------------------- 966// Files and packages 967 968// A File node represents a Go source file. 969// 970// The Comments list contains all comments in the source file in order of 971// appearance, including the comments that are pointed to from other nodes 972// via Doc and Comment fields. 973// 974// For correct printing of source code containing comments (using packages 975// go/format and go/printer), special care must be taken to update comments 976// when a File's syntax tree is modified: For printing, comments are interspersed 977// between tokens based on their position. If syntax tree nodes are 978// removed or moved, relevant comments in their vicinity must also be removed 979// (from the File.Comments list) or moved accordingly (by updating their 980// positions). A CommentMap may be used to facilitate some of these operations. 981// 982// Whether and how a comment is associated with a node depends on the 983// interpretation of the syntax tree by the manipulating program: Except for Doc 984// and Comment comments directly associated with nodes, the remaining comments 985// are "free-floating" (see also issues #18593, #20744). 986// 987type File struct { 988 Doc *CommentGroup // associated documentation; or nil 989 Package token.Pos // position of "package" keyword 990 Name *Ident // package name 991 Decls []Decl // top-level declarations; or nil 992 Scope *Scope // package scope (this file only) 993 Imports []*ImportSpec // imports in this file 994 Unresolved []*Ident // unresolved identifiers in this file 995 Comments []*CommentGroup // list of all comments in the source file 996} 997 998func (f *File) Pos() token.Pos { return f.Package } 999func (f *File) End() token.Pos { 1000 if n := len(f.Decls); n > 0 { 1001 return f.Decls[n-1].End() 1002 } 1003 return f.Name.End() 1004} 1005 1006// A Package node represents a set of source files 1007// collectively building a Go package. 1008// 1009type Package struct { 1010 Name string // package name 1011 Scope *Scope // package scope across all files 1012 Imports map[string]*Object // map of package id -> package object 1013 Files map[string]*File // Go source files by filename 1014} 1015 1016func (p *Package) Pos() token.Pos { return token.NoPos } 1017func (p *Package) End() token.Pos { return token.NoPos } 1018