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