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