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