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