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.
5 // Package ast declares the types used to represent syntax trees for Go
14 // ----------------------------------------------------------------------------
17 // There are 3 main classes of nodes: Expressions and type nodes,
18 // statement nodes, and declaration nodes. The node names usually
19 // match the corresponding Go spec production names to which they
20 // correspond. The node fields correspond to the individual parts
21 // of the respective productions.
23 // All nodes contain position information marking the beginning of
24 // the corresponding source text segment; it is accessible via the
25 // Pos accessor method. Nodes may contain additional position info
26 // for language constructs where comments may be found between parts
27 // of the construct (typically any larger, parenthesized subpart).
28 // That position information is needed to properly position comments
29 // when printing the construct.
31 // All node types implement the Node interface.
33 Pos() token.Pos // position of first character belonging to the node
34 End() token.Pos // position of first character immediately after the node
37 // All expression nodes implement the Expr interface.
43 // All statement nodes implement the Stmt interface.
49 // All declaration nodes implement the Decl interface.
55 // ----------------------------------------------------------------------------
58 // A Comment node represents a single //-style or /*-style comment.
60 // The Text field contains the comment text without carriage returns (\r) that
61 // may have been present in the source. Because a comment's end position is
62 // computed using len(Text), the position reported by End() does not match the
63 // true source end position for comments containing carriage returns.
65 Slash token.Pos // position of "/" starting the comment
66 Text string // comment text (excluding '\n' for //-style comments)
69 func (c *Comment) Pos() token.Pos { return c.Slash }
70 func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) }
72 // A CommentGroup represents a sequence of comments
73 // with no other tokens and no empty lines between.
74 type CommentGroup struct {
75 List []*Comment // len(List) > 0
78 func (g *CommentGroup) Pos() token.Pos { return g.List[0].Pos() }
79 func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() }
81 func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }
83 func stripTrailingWhitespace(s string) string {
85 for i > 0 && isWhitespace(s[i-1]) {
91 // Text returns the text of the comment.
92 // Comment markers (//, /*, and */), the first space of a line comment, and
93 // leading and trailing empty lines are removed.
94 // Comment directives like "//line" and "//go:noinline" are also removed.
95 // Multiple empty lines are reduced to one, and trailing space on lines is trimmed.
96 // Unless the result is empty, it is newline-terminated.
97 func (g *CommentGroup) Text() string {
101 comments := make([]string, len(g.List))
102 for i, c := range g.List {
106 lines := make([]string, 0, 10) // most comments are less than 10 lines
107 for _, c := range comments {
108 // Remove comment markers.
109 // The parser has given us exactly the comment text.
112 //-style comment (no newline at the end)
119 // strip first space - required for Example tests
124 // Ignore //go:noinline, //line, and so on.
132 // Split on newlines.
133 cl := strings.Split(c, "\n")
135 // Walk lines, stripping trailing white space and adding to list.
136 for _, l := range cl {
137 lines = append(lines, stripTrailingWhitespace(l))
141 // Remove leading blank lines; convert runs of
142 // interior blank lines to a single blank line.
144 for _, line := range lines {
145 if line != "" || n > 0 && lines[n-1] != "" {
152 // Add final "" entry to get trailing newline from Join.
153 if n > 0 && lines[n-1] != "" {
154 lines = append(lines, "")
157 return strings.Join(lines, "\n")
160 // isDirective reports whether c is a comment directive.
161 // This code is also in go/printer.
162 func isDirective(c string) bool {
163 // "//line " is a line directive.
164 // "//extern " is for gccgo.
165 // "//export " is for cgo.
166 // (The // has been removed.)
167 if strings.HasPrefix(c, "line ") || strings.HasPrefix(c, "extern ") || strings.HasPrefix(c, "export ") {
171 // "//[a-z0-9]+:[a-z0-9]"
172 // (The // has been removed.)
173 colon := strings.Index(c, ":")
174 if colon <= 0 || colon+1 >= len(c) {
177 for i := 0; i <= colon+1; i++ {
182 if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') {
189 // ----------------------------------------------------------------------------
190 // Expressions and types
192 // A Field represents a Field declaration list in a struct type,
193 // a method list in an interface type, or a parameter/result declaration
195 // Field.Names is nil for unnamed parameters (parameter lists which only contain types)
196 // and embedded struct fields. In the latter case, the field name is the type name.
198 Doc *CommentGroup // associated documentation; or nil
199 Names []*Ident // field/method/(type) parameter names; or nil
200 Type Expr // field/method/parameter type; or nil
201 Tag *BasicLit // field tag; or nil
202 Comment *CommentGroup // line comments; or nil
205 func (f *Field) Pos() token.Pos {
206 if len(f.Names) > 0 {
207 return f.Names[0].Pos()
215 func (f *Field) End() token.Pos {
222 if len(f.Names) > 0 {
223 return f.Names[len(f.Names)-1].End()
228 // A FieldList represents a list of Fields, enclosed by parentheses,
229 // curly braces, or square brackets.
230 type FieldList struct {
231 Opening token.Pos // position of opening parenthesis/brace/bracket, if any
232 List []*Field // field list; or nil
233 Closing token.Pos // position of closing parenthesis/brace/bracket, if any
236 func (f *FieldList) Pos() token.Pos {
237 if f.Opening.IsValid() {
240 // the list should not be empty in this case;
241 // be conservative and guard against bad ASTs
243 return f.List[0].Pos()
248 func (f *FieldList) End() token.Pos {
249 if f.Closing.IsValid() {
252 // the list should not be empty in this case;
253 // be conservative and guard against bad ASTs
254 if n := len(f.List); n > 0 {
255 return f.List[n-1].End()
260 // NumFields returns the number of parameters or struct fields represented by a FieldList.
261 func (f *FieldList) NumFields() int {
264 for _, g := range f.List {
275 // An expression is represented by a tree consisting of one
276 // or more of the following concrete expression nodes.
278 // A BadExpr node is a placeholder for an expression containing
279 // syntax errors for which a correct expression node cannot be
283 From, To token.Pos // position range of bad expression
286 // An Ident node represents an identifier.
288 NamePos token.Pos // identifier position
289 Name string // identifier name
290 Obj *Object // denoted object; or nil
293 // An Ellipsis node stands for the "..." type in a
294 // parameter list or the "..." length in an array type.
297 Ellipsis token.Pos // position of "..."
298 Elt Expr // ellipsis element type (parameter lists only); or nil
301 // A BasicLit node represents a literal of basic type.
303 ValuePos token.Pos // literal position
304 Kind token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
305 Value string // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o`
308 // A FuncLit node represents a function literal.
310 Type *FuncType // function type
311 Body *BlockStmt // function body
314 // A CompositeLit node represents a composite literal.
315 CompositeLit struct {
316 Type Expr // literal type; or nil
317 Lbrace token.Pos // position of "{"
318 Elts []Expr // list of composite elements; or nil
319 Rbrace token.Pos // position of "}"
320 Incomplete bool // true if (source) expressions are missing in the Elts list
323 // A ParenExpr node represents a parenthesized expression.
325 Lparen token.Pos // position of "("
326 X Expr // parenthesized expression
327 Rparen token.Pos // position of ")"
330 // A SelectorExpr node represents an expression followed by a selector.
331 SelectorExpr struct {
333 Sel *Ident // field selector
336 // An IndexExpr node represents an expression followed by an index.
339 Lbrack token.Pos // position of "["
340 Index Expr // index expression
341 Rbrack token.Pos // position of "]"
344 // An IndexListExpr node represents an expression followed by multiple
346 IndexListExpr struct {
348 Lbrack token.Pos // position of "["
349 Indices []Expr // index expressions
350 Rbrack token.Pos // position of "]"
353 // A SliceExpr node represents an expression followed by slice indices.
356 Lbrack token.Pos // position of "["
357 Low Expr // begin of slice range; or nil
358 High Expr // end of slice range; or nil
359 Max Expr // maximum capacity of slice; or nil
360 Slice3 bool // true if 3-index slice (2 colons present)
361 Rbrack token.Pos // position of "]"
364 // A TypeAssertExpr node represents an expression followed by a
367 TypeAssertExpr struct {
369 Lparen token.Pos // position of "("
370 Type Expr // asserted type; nil means type switch X.(type)
371 Rparen token.Pos // position of ")"
374 // A CallExpr node represents an expression followed by an argument list.
376 Fun Expr // function expression
377 Lparen token.Pos // position of "("
378 Args []Expr // function arguments; or nil
379 Ellipsis token.Pos // position of "..." (token.NoPos if there is no "...")
380 Rparen token.Pos // position of ")"
383 // A StarExpr node represents an expression of the form "*" Expression.
384 // Semantically it could be a unary "*" expression, or a pointer type.
387 Star token.Pos // position of "*"
391 // A UnaryExpr node represents a unary expression.
392 // Unary "*" expressions are represented via StarExpr nodes.
395 OpPos token.Pos // position of Op
396 Op token.Token // operator
400 // A BinaryExpr node represents a binary expression.
402 X Expr // left operand
403 OpPos token.Pos // position of Op
404 Op token.Token // operator
405 Y Expr // right operand
408 // A KeyValueExpr node represents (key : value) pairs
409 // in composite literals.
411 KeyValueExpr struct {
413 Colon token.Pos // position of ":"
418 // The direction of a channel type is indicated by a bit
419 // mask including one or both of the following constants.
423 SEND ChanDir = 1 << iota
427 // A type is represented by a tree consisting of one
428 // or more of the following type-specific expression
431 // An ArrayType node represents an array or slice type.
433 Lbrack token.Pos // position of "["
434 Len Expr // Ellipsis node for [...]T array types, nil for slice types
435 Elt Expr // element type
438 // A StructType node represents a struct type.
440 Struct token.Pos // position of "struct" keyword
441 Fields *FieldList // list of field declarations
442 Incomplete bool // true if (source) fields are missing in the Fields list
445 // Pointer types are represented via StarExpr nodes.
447 // A FuncType node represents a function type.
449 Func token.Pos // position of "func" keyword (token.NoPos if there is no "func")
450 TypeParams *FieldList // type parameters; or nil
451 Params *FieldList // (incoming) parameters; non-nil
452 Results *FieldList // (outgoing) results; or nil
455 // An InterfaceType node represents an interface type.
456 InterfaceType struct {
457 Interface token.Pos // position of "interface" keyword
458 Methods *FieldList // list of embedded interfaces, methods, or types
459 Incomplete bool // true if (source) methods or types are missing in the Methods list
462 // A MapType node represents a map type.
464 Map token.Pos // position of "map" keyword
469 // A ChanType node represents a channel type.
471 Begin token.Pos // position of "chan" keyword or "<-" (whichever comes first)
472 Arrow token.Pos // position of "<-" (token.NoPos if there is no "<-")
473 Dir ChanDir // channel direction
474 Value Expr // value type
478 // Pos and End implementations for expression/type nodes.
480 func (x *BadExpr) Pos() token.Pos { return x.From }
481 func (x *Ident) Pos() token.Pos { return x.NamePos }
482 func (x *Ellipsis) Pos() token.Pos { return x.Ellipsis }
483 func (x *BasicLit) Pos() token.Pos { return x.ValuePos }
484 func (x *FuncLit) Pos() token.Pos { return x.Type.Pos() }
485 func (x *CompositeLit) Pos() token.Pos {
491 func (x *ParenExpr) Pos() token.Pos { return x.Lparen }
492 func (x *SelectorExpr) Pos() token.Pos { return x.X.Pos() }
493 func (x *IndexExpr) Pos() token.Pos { return x.X.Pos() }
494 func (x *IndexListExpr) Pos() token.Pos { return x.X.Pos() }
495 func (x *SliceExpr) Pos() token.Pos { return x.X.Pos() }
496 func (x *TypeAssertExpr) Pos() token.Pos { return x.X.Pos() }
497 func (x *CallExpr) Pos() token.Pos { return x.Fun.Pos() }
498 func (x *StarExpr) Pos() token.Pos { return x.Star }
499 func (x *UnaryExpr) Pos() token.Pos { return x.OpPos }
500 func (x *BinaryExpr) Pos() token.Pos { return x.X.Pos() }
501 func (x *KeyValueExpr) Pos() token.Pos { return x.Key.Pos() }
502 func (x *ArrayType) Pos() token.Pos { return x.Lbrack }
503 func (x *StructType) Pos() token.Pos { return x.Struct }
504 func (x *FuncType) Pos() token.Pos {
505 if x.Func.IsValid() || x.Params == nil { // see issue 3870
508 return x.Params.Pos() // interface method declarations have no "func" keyword
510 func (x *InterfaceType) Pos() token.Pos { return x.Interface }
511 func (x *MapType) Pos() token.Pos { return x.Map }
512 func (x *ChanType) Pos() token.Pos { return x.Begin }
514 func (x *BadExpr) End() token.Pos { return x.To }
515 func (x *Ident) End() token.Pos { return token.Pos(int(x.NamePos) + len(x.Name)) }
516 func (x *Ellipsis) End() token.Pos {
520 return x.Ellipsis + 3 // len("...")
522 func (x *BasicLit) End() token.Pos { return token.Pos(int(x.ValuePos) + len(x.Value)) }
523 func (x *FuncLit) End() token.Pos { return x.Body.End() }
524 func (x *CompositeLit) End() token.Pos { return x.Rbrace + 1 }
525 func (x *ParenExpr) End() token.Pos { return x.Rparen + 1 }
526 func (x *SelectorExpr) End() token.Pos { return x.Sel.End() }
527 func (x *IndexExpr) End() token.Pos { return x.Rbrack + 1 }
528 func (x *IndexListExpr) End() token.Pos { return x.Rbrack + 1 }
529 func (x *SliceExpr) End() token.Pos { return x.Rbrack + 1 }
530 func (x *TypeAssertExpr) End() token.Pos { return x.Rparen + 1 }
531 func (x *CallExpr) End() token.Pos { return x.Rparen + 1 }
532 func (x *StarExpr) End() token.Pos { return x.X.End() }
533 func (x *UnaryExpr) End() token.Pos { return x.X.End() }
534 func (x *BinaryExpr) End() token.Pos { return x.Y.End() }
535 func (x *KeyValueExpr) End() token.Pos { return x.Value.End() }
536 func (x *ArrayType) End() token.Pos { return x.Elt.End() }
537 func (x *StructType) End() token.Pos { return x.Fields.End() }
538 func (x *FuncType) End() token.Pos {
539 if x.Results != nil {
540 return x.Results.End()
542 return x.Params.End()
544 func (x *InterfaceType) End() token.Pos { return x.Methods.End() }
545 func (x *MapType) End() token.Pos { return x.Value.End() }
546 func (x *ChanType) End() token.Pos { return x.Value.End() }
548 // exprNode() ensures that only expression/type nodes can be
549 // assigned to an Expr.
550 func (*BadExpr) exprNode() {}
551 func (*Ident) exprNode() {}
552 func (*Ellipsis) exprNode() {}
553 func (*BasicLit) exprNode() {}
554 func (*FuncLit) exprNode() {}
555 func (*CompositeLit) exprNode() {}
556 func (*ParenExpr) exprNode() {}
557 func (*SelectorExpr) exprNode() {}
558 func (*IndexExpr) exprNode() {}
559 func (*IndexListExpr) exprNode() {}
560 func (*SliceExpr) exprNode() {}
561 func (*TypeAssertExpr) exprNode() {}
562 func (*CallExpr) exprNode() {}
563 func (*StarExpr) exprNode() {}
564 func (*UnaryExpr) exprNode() {}
565 func (*BinaryExpr) exprNode() {}
566 func (*KeyValueExpr) exprNode() {}
568 func (*ArrayType) exprNode() {}
569 func (*StructType) exprNode() {}
570 func (*FuncType) exprNode() {}
571 func (*InterfaceType) exprNode() {}
572 func (*MapType) exprNode() {}
573 func (*ChanType) exprNode() {}
575 // ----------------------------------------------------------------------------
576 // Convenience functions for Idents
578 // NewIdent creates a new Ident without position.
579 // Useful for ASTs generated by code other than the Go parser.
580 func NewIdent(name string) *Ident { return &Ident{token.NoPos, name, nil} }
582 // IsExported reports whether name starts with an upper-case letter.
583 func IsExported(name string) bool { return token.IsExported(name) }
585 // IsExported reports whether id starts with an upper-case letter.
586 func (id *Ident) IsExported() bool { return token.IsExported(id.Name) }
588 func (id *Ident) String() string {
595 // ----------------------------------------------------------------------------
598 // A statement is represented by a tree consisting of one
599 // or more of the following concrete statement nodes.
601 // A BadStmt node is a placeholder for statements containing
602 // syntax errors for which no correct statement nodes can be
606 From, To token.Pos // position range of bad statement
609 // A DeclStmt node represents a declaration in a statement list.
611 Decl Decl // *GenDecl with CONST, TYPE, or VAR token
614 // An EmptyStmt node represents an empty statement.
615 // The "position" of the empty statement is the position
616 // of the immediately following (explicit or implicit) semicolon.
619 Semicolon token.Pos // position of following ";"
620 Implicit bool // if set, ";" was omitted in the source
623 // A LabeledStmt node represents a labeled statement.
626 Colon token.Pos // position of ":"
630 // An ExprStmt node represents a (stand-alone) expression
631 // in a statement list.
637 // A SendStmt node represents a send statement.
640 Arrow token.Pos // position of "<-"
644 // An IncDecStmt node represents an increment or decrement statement.
647 TokPos token.Pos // position of Tok
648 Tok token.Token // INC or DEC
651 // An AssignStmt node represents an assignment or
652 // a short variable declaration.
656 TokPos token.Pos // position of Tok
657 Tok token.Token // assignment token, DEFINE
661 // A GoStmt node represents a go statement.
663 Go token.Pos // position of "go" keyword
667 // A DeferStmt node represents a defer statement.
669 Defer token.Pos // position of "defer" keyword
673 // A ReturnStmt node represents a return statement.
675 Return token.Pos // position of "return" keyword
676 Results []Expr // result expressions; or nil
679 // A BranchStmt node represents a break, continue, goto,
680 // or fallthrough statement.
683 TokPos token.Pos // position of Tok
684 Tok token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
685 Label *Ident // label name; or nil
688 // A BlockStmt node represents a braced statement list.
690 Lbrace token.Pos // position of "{"
692 Rbrace token.Pos // position of "}", if any (may be absent due to syntax error)
695 // An IfStmt node represents an if statement.
697 If token.Pos // position of "if" keyword
698 Init Stmt // initialization statement; or nil
699 Cond Expr // condition
701 Else Stmt // else branch; or nil
704 // A CaseClause represents a case of an expression or type switch statement.
706 Case token.Pos // position of "case" or "default" keyword
707 List []Expr // list of expressions or types; nil means default case
708 Colon token.Pos // position of ":"
709 Body []Stmt // statement list; or nil
712 // A SwitchStmt node represents an expression switch statement.
714 Switch token.Pos // position of "switch" keyword
715 Init Stmt // initialization statement; or nil
716 Tag Expr // tag expression; or nil
717 Body *BlockStmt // CaseClauses only
720 // A TypeSwitchStmt node represents a type switch statement.
721 TypeSwitchStmt struct {
722 Switch token.Pos // position of "switch" keyword
723 Init Stmt // initialization statement; or nil
724 Assign Stmt // x := y.(type) or y.(type)
725 Body *BlockStmt // CaseClauses only
728 // A CommClause node represents a case of a select statement.
730 Case token.Pos // position of "case" or "default" keyword
731 Comm Stmt // send or receive statement; nil means default case
732 Colon token.Pos // position of ":"
733 Body []Stmt // statement list; or nil
736 // A SelectStmt node represents a select statement.
738 Select token.Pos // position of "select" keyword
739 Body *BlockStmt // CommClauses only
742 // A ForStmt represents a for statement.
744 For token.Pos // position of "for" keyword
745 Init Stmt // initialization statement; or nil
746 Cond Expr // condition; or nil
747 Post Stmt // post iteration statement; or nil
751 // A RangeStmt represents a for statement with a range clause.
753 For token.Pos // position of "for" keyword
754 Key, Value Expr // Key, Value may be nil
755 TokPos token.Pos // position of Tok; invalid if Key == nil
756 Tok token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE
757 Range token.Pos // position of "range" keyword
758 X Expr // value to range over
763 // Pos and End implementations for statement nodes.
765 func (s *BadStmt) Pos() token.Pos { return s.From }
766 func (s *DeclStmt) Pos() token.Pos { return s.Decl.Pos() }
767 func (s *EmptyStmt) Pos() token.Pos { return s.Semicolon }
768 func (s *LabeledStmt) Pos() token.Pos { return s.Label.Pos() }
769 func (s *ExprStmt) Pos() token.Pos { return s.X.Pos() }
770 func (s *SendStmt) Pos() token.Pos { return s.Chan.Pos() }
771 func (s *IncDecStmt) Pos() token.Pos { return s.X.Pos() }
772 func (s *AssignStmt) Pos() token.Pos { return s.Lhs[0].Pos() }
773 func (s *GoStmt) Pos() token.Pos { return s.Go }
774 func (s *DeferStmt) Pos() token.Pos { return s.Defer }
775 func (s *ReturnStmt) Pos() token.Pos { return s.Return }
776 func (s *BranchStmt) Pos() token.Pos { return s.TokPos }
777 func (s *BlockStmt) Pos() token.Pos { return s.Lbrace }
778 func (s *IfStmt) Pos() token.Pos { return s.If }
779 func (s *CaseClause) Pos() token.Pos { return s.Case }
780 func (s *SwitchStmt) Pos() token.Pos { return s.Switch }
781 func (s *TypeSwitchStmt) Pos() token.Pos { return s.Switch }
782 func (s *CommClause) Pos() token.Pos { return s.Case }
783 func (s *SelectStmt) Pos() token.Pos { return s.Select }
784 func (s *ForStmt) Pos() token.Pos { return s.For }
785 func (s *RangeStmt) Pos() token.Pos { return s.For }
787 func (s *BadStmt) End() token.Pos { return s.To }
788 func (s *DeclStmt) End() token.Pos { return s.Decl.End() }
789 func (s *EmptyStmt) End() token.Pos {
793 return s.Semicolon + 1 /* len(";") */
795 func (s *LabeledStmt) End() token.Pos { return s.Stmt.End() }
796 func (s *ExprStmt) End() token.Pos { return s.X.End() }
797 func (s *SendStmt) End() token.Pos { return s.Value.End() }
798 func (s *IncDecStmt) End() token.Pos {
799 return s.TokPos + 2 /* len("++") */
801 func (s *AssignStmt) End() token.Pos { return s.Rhs[len(s.Rhs)-1].End() }
802 func (s *GoStmt) End() token.Pos { return s.Call.End() }
803 func (s *DeferStmt) End() token.Pos { return s.Call.End() }
804 func (s *ReturnStmt) End() token.Pos {
805 if n := len(s.Results); n > 0 {
806 return s.Results[n-1].End()
808 return s.Return + 6 // len("return")
810 func (s *BranchStmt) End() token.Pos {
814 return token.Pos(int(s.TokPos) + len(s.Tok.String()))
816 func (s *BlockStmt) End() token.Pos {
817 if s.Rbrace.IsValid() {
820 if n := len(s.List); n > 0 {
821 return s.List[n-1].End()
825 func (s *IfStmt) End() token.Pos {
831 func (s *CaseClause) End() token.Pos {
832 if n := len(s.Body); n > 0 {
833 return s.Body[n-1].End()
837 func (s *SwitchStmt) End() token.Pos { return s.Body.End() }
838 func (s *TypeSwitchStmt) End() token.Pos { return s.Body.End() }
839 func (s *CommClause) End() token.Pos {
840 if n := len(s.Body); n > 0 {
841 return s.Body[n-1].End()
845 func (s *SelectStmt) End() token.Pos { return s.Body.End() }
846 func (s *ForStmt) End() token.Pos { return s.Body.End() }
847 func (s *RangeStmt) End() token.Pos { return s.Body.End() }
849 // stmtNode() ensures that only statement nodes can be
850 // assigned to a Stmt.
851 func (*BadStmt) stmtNode() {}
852 func (*DeclStmt) stmtNode() {}
853 func (*EmptyStmt) stmtNode() {}
854 func (*LabeledStmt) stmtNode() {}
855 func (*ExprStmt) stmtNode() {}
856 func (*SendStmt) stmtNode() {}
857 func (*IncDecStmt) stmtNode() {}
858 func (*AssignStmt) stmtNode() {}
859 func (*GoStmt) stmtNode() {}
860 func (*DeferStmt) stmtNode() {}
861 func (*ReturnStmt) stmtNode() {}
862 func (*BranchStmt) stmtNode() {}
863 func (*BlockStmt) stmtNode() {}
864 func (*IfStmt) stmtNode() {}
865 func (*CaseClause) stmtNode() {}
866 func (*SwitchStmt) stmtNode() {}
867 func (*TypeSwitchStmt) stmtNode() {}
868 func (*CommClause) stmtNode() {}
869 func (*SelectStmt) stmtNode() {}
870 func (*ForStmt) stmtNode() {}
871 func (*RangeStmt) stmtNode() {}
873 // ----------------------------------------------------------------------------
876 // A Spec node represents a single (non-parenthesized) import,
877 // constant, type, or variable declaration.
879 // The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
885 // An ImportSpec node represents a single package import.
887 Doc *CommentGroup // associated documentation; or nil
888 Name *Ident // local package name (including "."); or nil
889 Path *BasicLit // import path
890 Comment *CommentGroup // line comments; or nil
891 EndPos token.Pos // end of spec (overrides Path.Pos if nonzero)
894 // A ValueSpec node represents a constant or variable declaration
895 // (ConstSpec or VarSpec production).
898 Doc *CommentGroup // associated documentation; or nil
899 Names []*Ident // value names (len(Names) > 0)
900 Type Expr // value type; or nil
901 Values []Expr // initial values; or nil
902 Comment *CommentGroup // line comments; or nil
905 // A TypeSpec node represents a type declaration (TypeSpec production).
907 Doc *CommentGroup // associated documentation; or nil
908 Name *Ident // type name
909 TypeParams *FieldList // type parameters; or nil
910 Assign token.Pos // position of '=', if any
911 Type Expr // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
912 Comment *CommentGroup // line comments; or nil
916 // Pos and End implementations for spec nodes.
918 func (s *ImportSpec) Pos() token.Pos {
924 func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() }
925 func (s *TypeSpec) Pos() token.Pos { return s.Name.Pos() }
927 func (s *ImportSpec) End() token.Pos {
934 func (s *ValueSpec) End() token.Pos {
935 if n := len(s.Values); n > 0 {
936 return s.Values[n-1].End()
941 return s.Names[len(s.Names)-1].End()
943 func (s *TypeSpec) End() token.Pos { return s.Type.End() }
945 // specNode() ensures that only spec nodes can be
946 // assigned to a Spec.
947 func (*ImportSpec) specNode() {}
948 func (*ValueSpec) specNode() {}
949 func (*TypeSpec) specNode() {}
951 // A declaration is represented by one of the following declaration nodes.
953 // A BadDecl node is a placeholder for a declaration containing
954 // syntax errors for which a correct declaration node cannot be
958 From, To token.Pos // position range of bad declaration
961 // A GenDecl node (generic declaration node) represents an import,
962 // constant, type or variable declaration. A valid Lparen position
963 // (Lparen.IsValid()) indicates a parenthesized declaration.
965 // Relationship between Tok value and Specs element type:
967 // token.IMPORT *ImportSpec
968 // token.CONST *ValueSpec
969 // token.TYPE *TypeSpec
970 // token.VAR *ValueSpec
973 Doc *CommentGroup // associated documentation; or nil
974 TokPos token.Pos // position of Tok
975 Tok token.Token // IMPORT, CONST, TYPE, or VAR
976 Lparen token.Pos // position of '(', if any
978 Rparen token.Pos // position of ')', if any
981 // A FuncDecl node represents a function declaration.
983 Doc *CommentGroup // associated documentation; or nil
984 Recv *FieldList // receiver (methods); or nil (functions)
985 Name *Ident // function/method name
986 Type *FuncType // function signature: type and value parameters, results, and position of "func" keyword
987 Body *BlockStmt // function body; or nil for external (non-Go) function
991 // Pos and End implementations for declaration nodes.
993 func (d *BadDecl) Pos() token.Pos { return d.From }
994 func (d *GenDecl) Pos() token.Pos { return d.TokPos }
995 func (d *FuncDecl) Pos() token.Pos { return d.Type.Pos() }
997 func (d *BadDecl) End() token.Pos { return d.To }
998 func (d *GenDecl) End() token.Pos {
999 if d.Rparen.IsValid() {
1002 return d.Specs[0].End()
1004 func (d *FuncDecl) End() token.Pos {
1011 // declNode() ensures that only declaration nodes can be
1012 // assigned to a Decl.
1013 func (*BadDecl) declNode() {}
1014 func (*GenDecl) declNode() {}
1015 func (*FuncDecl) declNode() {}
1017 // ----------------------------------------------------------------------------
1018 // Files and packages
1020 // A File node represents a Go source file.
1022 // The Comments list contains all comments in the source file in order of
1023 // appearance, including the comments that are pointed to from other nodes
1024 // via Doc and Comment fields.
1026 // For correct printing of source code containing comments (using packages
1027 // go/format and go/printer), special care must be taken to update comments
1028 // when a File's syntax tree is modified: For printing, comments are interspersed
1029 // between tokens based on their position. If syntax tree nodes are
1030 // removed or moved, relevant comments in their vicinity must also be removed
1031 // (from the File.Comments list) or moved accordingly (by updating their
1032 // positions). A CommentMap may be used to facilitate some of these operations.
1034 // Whether and how a comment is associated with a node depends on the
1035 // interpretation of the syntax tree by the manipulating program: Except for Doc
1036 // and Comment comments directly associated with nodes, the remaining comments
1037 // are "free-floating" (see also issues #18593, #20744).
1039 Doc *CommentGroup // associated documentation; or nil
1040 Package token.Pos // position of "package" keyword
1041 Name *Ident // package name
1042 Decls []Decl // top-level declarations; or nil
1044 FileStart, FileEnd token.Pos // start and end of entire file
1045 Scope *Scope // package scope (this file only)
1046 Imports []*ImportSpec // imports in this file
1047 Unresolved []*Ident // unresolved identifiers in this file
1048 Comments []*CommentGroup // list of all comments in the source file
1049 GoVersion string // minimum Go version required by //go:build or // +build directives
1052 // Pos returns the position of the package declaration.
1053 // (Use FileStart for the start of the entire file.)
1054 func (f *File) Pos() token.Pos { return f.Package }
1056 // End returns the end of the last declaration in the file.
1057 // (Use FileEnd for the end of the entire file.)
1058 func (f *File) End() token.Pos {
1059 if n := len(f.Decls); n > 0 {
1060 return f.Decls[n-1].End()
1065 // A Package node represents a set of source files
1066 // collectively building a Go package.
1067 type Package struct {
1068 Name string // package name
1069 Scope *Scope // package scope across all files
1070 Imports map[string]*Object // map of package id -> package object
1071 Files map[string]*File // Go source files by filename
1074 func (p *Package) Pos() token.Pos { return token.NoPos }
1075 func (p *Package) End() token.Pos { return token.NoPos }