]> Cypherpunks.ru repositories - gostls13.git/blob - src/go/ast/ast.go
c43905261050a179e23509160a219be80cf87393
[gostls13.git] / src / go / ast / ast.go
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 package ast
8
9 import (
10         "go/token"
11         "strings"
12 )
13
14 // ----------------------------------------------------------------------------
15 // Interfaces
16 //
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.
22 //
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.
30
31 // All node types implement the Node interface.
32 type 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
35 }
36
37 // All expression nodes implement the Expr interface.
38 type Expr interface {
39         Node
40         exprNode()
41 }
42
43 // All statement nodes implement the Stmt interface.
44 type Stmt interface {
45         Node
46         stmtNode()
47 }
48
49 // All declaration nodes implement the Decl interface.
50 type Decl interface {
51         Node
52         declNode()
53 }
54
55 // ----------------------------------------------------------------------------
56 // Comments
57
58 // A Comment node represents a single //-style or /*-style comment.
59 //
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.
64 type Comment struct {
65         Slash token.Pos // position of "/" starting the comment
66         Text  string    // comment text (excluding '\n' for //-style comments)
67 }
68
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)) }
71
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
76 }
77
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() }
80
81 func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }
82
83 func stripTrailingWhitespace(s string) string {
84         i := len(s)
85         for i > 0 && isWhitespace(s[i-1]) {
86                 i--
87         }
88         return s[0:i]
89 }
90
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 {
98         if g == nil {
99                 return ""
100         }
101         comments := make([]string, len(g.List))
102         for i, c := range g.List {
103                 comments[i] = c.Text
104         }
105
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.
110                 switch c[1] {
111                 case '/':
112                         //-style comment (no newline at the end)
113                         c = c[2:]
114                         if len(c) == 0 {
115                                 // empty line
116                                 break
117                         }
118                         if c[0] == ' ' {
119                                 // strip first space - required for Example tests
120                                 c = c[1:]
121                                 break
122                         }
123                         if isDirective(c) {
124                                 // Ignore //go:noinline, //line, and so on.
125                                 continue
126                         }
127                 case '*':
128                         /*-style comment */
129                         c = c[2 : len(c)-2]
130                 }
131
132                 // Split on newlines.
133                 cl := strings.Split(c, "\n")
134
135                 // Walk lines, stripping trailing white space and adding to list.
136                 for _, l := range cl {
137                         lines = append(lines, stripTrailingWhitespace(l))
138                 }
139         }
140
141         // Remove leading blank lines; convert runs of
142         // interior blank lines to a single blank line.
143         n := 0
144         for _, line := range lines {
145                 if line != "" || n > 0 && lines[n-1] != "" {
146                         lines[n] = line
147                         n++
148                 }
149         }
150         lines = lines[0:n]
151
152         // Add final "" entry to get trailing newline from Join.
153         if n > 0 && lines[n-1] != "" {
154                 lines = append(lines, "")
155         }
156
157         return strings.Join(lines, "\n")
158 }
159
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 ") {
168                 return true
169         }
170
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) {
175                 return false
176         }
177         for i := 0; i <= colon+1; i++ {
178                 if i == colon {
179                         continue
180                 }
181                 b := c[i]
182                 if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') {
183                         return false
184                 }
185         }
186         return true
187 }
188
189 // ----------------------------------------------------------------------------
190 // Expressions and types
191
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
194 // in a signature.
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.
197 type Field struct {
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
203 }
204
205 func (f *Field) Pos() token.Pos {
206         if len(f.Names) > 0 {
207                 return f.Names[0].Pos()
208         }
209         if f.Type != nil {
210                 return f.Type.Pos()
211         }
212         return token.NoPos
213 }
214
215 func (f *Field) End() token.Pos {
216         if f.Tag != nil {
217                 return f.Tag.End()
218         }
219         if f.Type != nil {
220                 return f.Type.End()
221         }
222         if len(f.Names) > 0 {
223                 return f.Names[len(f.Names)-1].End()
224         }
225         return token.NoPos
226 }
227
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
234 }
235
236 func (f *FieldList) Pos() token.Pos {
237         if f.Opening.IsValid() {
238                 return f.Opening
239         }
240         // the list should not be empty in this case;
241         // be conservative and guard against bad ASTs
242         if len(f.List) > 0 {
243                 return f.List[0].Pos()
244         }
245         return token.NoPos
246 }
247
248 func (f *FieldList) End() token.Pos {
249         if f.Closing.IsValid() {
250                 return f.Closing + 1
251         }
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()
256         }
257         return token.NoPos
258 }
259
260 // NumFields returns the number of parameters or struct fields represented by a FieldList.
261 func (f *FieldList) NumFields() int {
262         n := 0
263         if f != nil {
264                 for _, g := range f.List {
265                         m := len(g.Names)
266                         if m == 0 {
267                                 m = 1
268                         }
269                         n += m
270                 }
271         }
272         return n
273 }
274
275 // An expression is represented by a tree consisting of one
276 // or more of the following concrete expression nodes.
277 type (
278         // A BadExpr node is a placeholder for an expression containing
279         // syntax errors for which a correct expression node cannot be
280         // created.
281         //
282         BadExpr struct {
283                 From, To token.Pos // position range of bad expression
284         }
285
286         // An Ident node represents an identifier.
287         Ident struct {
288                 NamePos token.Pos // identifier position
289                 Name    string    // identifier name
290                 Obj     *Object   // denoted object; or nil
291         }
292
293         // An Ellipsis node stands for the "..." type in a
294         // parameter list or the "..." length in an array type.
295         //
296         Ellipsis struct {
297                 Ellipsis token.Pos // position of "..."
298                 Elt      Expr      // ellipsis element type (parameter lists only); or nil
299         }
300
301         // A BasicLit node represents a literal of basic type.
302         BasicLit struct {
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`
306         }
307
308         // A FuncLit node represents a function literal.
309         FuncLit struct {
310                 Type *FuncType  // function type
311                 Body *BlockStmt // function body
312         }
313
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
321         }
322
323         // A ParenExpr node represents a parenthesized expression.
324         ParenExpr struct {
325                 Lparen token.Pos // position of "("
326                 X      Expr      // parenthesized expression
327                 Rparen token.Pos // position of ")"
328         }
329
330         // A SelectorExpr node represents an expression followed by a selector.
331         SelectorExpr struct {
332                 X   Expr   // expression
333                 Sel *Ident // field selector
334         }
335
336         // An IndexExpr node represents an expression followed by an index.
337         IndexExpr struct {
338                 X      Expr      // expression
339                 Lbrack token.Pos // position of "["
340                 Index  Expr      // index expression
341                 Rbrack token.Pos // position of "]"
342         }
343
344         // An IndexListExpr node represents an expression followed by multiple
345         // indices.
346         IndexListExpr struct {
347                 X       Expr      // expression
348                 Lbrack  token.Pos // position of "["
349                 Indices []Expr    // index expressions
350                 Rbrack  token.Pos // position of "]"
351         }
352
353         // A SliceExpr node represents an expression followed by slice indices.
354         SliceExpr struct {
355                 X      Expr      // expression
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 "]"
362         }
363
364         // A TypeAssertExpr node represents an expression followed by a
365         // type assertion.
366         //
367         TypeAssertExpr struct {
368                 X      Expr      // expression
369                 Lparen token.Pos // position of "("
370                 Type   Expr      // asserted type; nil means type switch X.(type)
371                 Rparen token.Pos // position of ")"
372         }
373
374         // A CallExpr node represents an expression followed by an argument list.
375         CallExpr struct {
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 ")"
381         }
382
383         // A StarExpr node represents an expression of the form "*" Expression.
384         // Semantically it could be a unary "*" expression, or a pointer type.
385         //
386         StarExpr struct {
387                 Star token.Pos // position of "*"
388                 X    Expr      // operand
389         }
390
391         // A UnaryExpr node represents a unary expression.
392         // Unary "*" expressions are represented via StarExpr nodes.
393         //
394         UnaryExpr struct {
395                 OpPos token.Pos   // position of Op
396                 Op    token.Token // operator
397                 X     Expr        // operand
398         }
399
400         // A BinaryExpr node represents a binary expression.
401         BinaryExpr struct {
402                 X     Expr        // left operand
403                 OpPos token.Pos   // position of Op
404                 Op    token.Token // operator
405                 Y     Expr        // right operand
406         }
407
408         // A KeyValueExpr node represents (key : value) pairs
409         // in composite literals.
410         //
411         KeyValueExpr struct {
412                 Key   Expr
413                 Colon token.Pos // position of ":"
414                 Value Expr
415         }
416 )
417
418 // The direction of a channel type is indicated by a bit
419 // mask including one or both of the following constants.
420 type ChanDir int
421
422 const (
423         SEND ChanDir = 1 << iota
424         RECV
425 )
426
427 // A type is represented by a tree consisting of one
428 // or more of the following type-specific expression
429 // nodes.
430 type (
431         // An ArrayType node represents an array or slice type.
432         ArrayType struct {
433                 Lbrack token.Pos // position of "["
434                 Len    Expr      // Ellipsis node for [...]T array types, nil for slice types
435                 Elt    Expr      // element type
436         }
437
438         // A StructType node represents a struct type.
439         StructType struct {
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
443         }
444
445         // Pointer types are represented via StarExpr nodes.
446
447         // A FuncType node represents a function type.
448         FuncType struct {
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
453         }
454
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
460         }
461
462         // A MapType node represents a map type.
463         MapType struct {
464                 Map   token.Pos // position of "map" keyword
465                 Key   Expr
466                 Value Expr
467         }
468
469         // A ChanType node represents a channel type.
470         ChanType struct {
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
475         }
476 )
477
478 // Pos and End implementations for expression/type nodes.
479
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 {
486         if x.Type != nil {
487                 return x.Type.Pos()
488         }
489         return x.Lbrace
490 }
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
506                 return x.Func
507         }
508         return x.Params.Pos() // interface method declarations have no "func" keyword
509 }
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 }
513
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 {
517         if x.Elt != nil {
518                 return x.Elt.End()
519         }
520         return x.Ellipsis + 3 // len("...")
521 }
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()
541         }
542         return x.Params.End()
543 }
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() }
547
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()   {}
567
568 func (*ArrayType) exprNode()     {}
569 func (*StructType) exprNode()    {}
570 func (*FuncType) exprNode()      {}
571 func (*InterfaceType) exprNode() {}
572 func (*MapType) exprNode()       {}
573 func (*ChanType) exprNode()      {}
574
575 // ----------------------------------------------------------------------------
576 // Convenience functions for Idents
577
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} }
581
582 // IsExported reports whether name starts with an upper-case letter.
583 func IsExported(name string) bool { return token.IsExported(name) }
584
585 // IsExported reports whether id starts with an upper-case letter.
586 func (id *Ident) IsExported() bool { return token.IsExported(id.Name) }
587
588 func (id *Ident) String() string {
589         if id != nil {
590                 return id.Name
591         }
592         return "<nil>"
593 }
594
595 // ----------------------------------------------------------------------------
596 // Statements
597
598 // A statement is represented by a tree consisting of one
599 // or more of the following concrete statement nodes.
600 type (
601         // A BadStmt node is a placeholder for statements containing
602         // syntax errors for which no correct statement nodes can be
603         // created.
604         //
605         BadStmt struct {
606                 From, To token.Pos // position range of bad statement
607         }
608
609         // A DeclStmt node represents a declaration in a statement list.
610         DeclStmt struct {
611                 Decl Decl // *GenDecl with CONST, TYPE, or VAR token
612         }
613
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.
617         //
618         EmptyStmt struct {
619                 Semicolon token.Pos // position of following ";"
620                 Implicit  bool      // if set, ";" was omitted in the source
621         }
622
623         // A LabeledStmt node represents a labeled statement.
624         LabeledStmt struct {
625                 Label *Ident
626                 Colon token.Pos // position of ":"
627                 Stmt  Stmt
628         }
629
630         // An ExprStmt node represents a (stand-alone) expression
631         // in a statement list.
632         //
633         ExprStmt struct {
634                 X Expr // expression
635         }
636
637         // A SendStmt node represents a send statement.
638         SendStmt struct {
639                 Chan  Expr
640                 Arrow token.Pos // position of "<-"
641                 Value Expr
642         }
643
644         // An IncDecStmt node represents an increment or decrement statement.
645         IncDecStmt struct {
646                 X      Expr
647                 TokPos token.Pos   // position of Tok
648                 Tok    token.Token // INC or DEC
649         }
650
651         // An AssignStmt node represents an assignment or
652         // a short variable declaration.
653         //
654         AssignStmt struct {
655                 Lhs    []Expr
656                 TokPos token.Pos   // position of Tok
657                 Tok    token.Token // assignment token, DEFINE
658                 Rhs    []Expr
659         }
660
661         // A GoStmt node represents a go statement.
662         GoStmt struct {
663                 Go   token.Pos // position of "go" keyword
664                 Call *CallExpr
665         }
666
667         // A DeferStmt node represents a defer statement.
668         DeferStmt struct {
669                 Defer token.Pos // position of "defer" keyword
670                 Call  *CallExpr
671         }
672
673         // A ReturnStmt node represents a return statement.
674         ReturnStmt struct {
675                 Return  token.Pos // position of "return" keyword
676                 Results []Expr    // result expressions; or nil
677         }
678
679         // A BranchStmt node represents a break, continue, goto,
680         // or fallthrough statement.
681         //
682         BranchStmt struct {
683                 TokPos token.Pos   // position of Tok
684                 Tok    token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
685                 Label  *Ident      // label name; or nil
686         }
687
688         // A BlockStmt node represents a braced statement list.
689         BlockStmt struct {
690                 Lbrace token.Pos // position of "{"
691                 List   []Stmt
692                 Rbrace token.Pos // position of "}", if any (may be absent due to syntax error)
693         }
694
695         // An IfStmt node represents an if statement.
696         IfStmt struct {
697                 If   token.Pos // position of "if" keyword
698                 Init Stmt      // initialization statement; or nil
699                 Cond Expr      // condition
700                 Body *BlockStmt
701                 Else Stmt // else branch; or nil
702         }
703
704         // A CaseClause represents a case of an expression or type switch statement.
705         CaseClause struct {
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
710         }
711
712         // A SwitchStmt node represents an expression switch statement.
713         SwitchStmt struct {
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
718         }
719
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
726         }
727
728         // A CommClause node represents a case of a select statement.
729         CommClause struct {
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
734         }
735
736         // A SelectStmt node represents a select statement.
737         SelectStmt struct {
738                 Select token.Pos  // position of "select" keyword
739                 Body   *BlockStmt // CommClauses only
740         }
741
742         // A ForStmt represents a for statement.
743         ForStmt struct {
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
748                 Body *BlockStmt
749         }
750
751         // A RangeStmt represents a for statement with a range clause.
752         RangeStmt struct {
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
759                 Body       *BlockStmt
760         }
761 )
762
763 // Pos and End implementations for statement nodes.
764
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 }
786
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 {
790         if s.Implicit {
791                 return s.Semicolon
792         }
793         return s.Semicolon + 1 /* len(";") */
794 }
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("++") */
800 }
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()
807         }
808         return s.Return + 6 // len("return")
809 }
810 func (s *BranchStmt) End() token.Pos {
811         if s.Label != nil {
812                 return s.Label.End()
813         }
814         return token.Pos(int(s.TokPos) + len(s.Tok.String()))
815 }
816 func (s *BlockStmt) End() token.Pos {
817         if s.Rbrace.IsValid() {
818                 return s.Rbrace + 1
819         }
820         if n := len(s.List); n > 0 {
821                 return s.List[n-1].End()
822         }
823         return s.Lbrace + 1
824 }
825 func (s *IfStmt) End() token.Pos {
826         if s.Else != nil {
827                 return s.Else.End()
828         }
829         return s.Body.End()
830 }
831 func (s *CaseClause) End() token.Pos {
832         if n := len(s.Body); n > 0 {
833                 return s.Body[n-1].End()
834         }
835         return s.Colon + 1
836 }
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()
842         }
843         return s.Colon + 1
844 }
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() }
848
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()      {}
872
873 // ----------------------------------------------------------------------------
874 // Declarations
875
876 // A Spec node represents a single (non-parenthesized) import,
877 // constant, type, or variable declaration.
878 type (
879         // The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
880         Spec interface {
881                 Node
882                 specNode()
883         }
884
885         // An ImportSpec node represents a single package import.
886         ImportSpec struct {
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)
892         }
893
894         // A ValueSpec node represents a constant or variable declaration
895         // (ConstSpec or VarSpec production).
896         //
897         ValueSpec struct {
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
903         }
904
905         // A TypeSpec node represents a type declaration (TypeSpec production).
906         TypeSpec struct {
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
913         }
914 )
915
916 // Pos and End implementations for spec nodes.
917
918 func (s *ImportSpec) Pos() token.Pos {
919         if s.Name != nil {
920                 return s.Name.Pos()
921         }
922         return s.Path.Pos()
923 }
924 func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() }
925 func (s *TypeSpec) Pos() token.Pos  { return s.Name.Pos() }
926
927 func (s *ImportSpec) End() token.Pos {
928         if s.EndPos != 0 {
929                 return s.EndPos
930         }
931         return s.Path.End()
932 }
933
934 func (s *ValueSpec) End() token.Pos {
935         if n := len(s.Values); n > 0 {
936                 return s.Values[n-1].End()
937         }
938         if s.Type != nil {
939                 return s.Type.End()
940         }
941         return s.Names[len(s.Names)-1].End()
942 }
943 func (s *TypeSpec) End() token.Pos { return s.Type.End() }
944
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()   {}
950
951 // A declaration is represented by one of the following declaration nodes.
952 type (
953         // A BadDecl node is a placeholder for a declaration containing
954         // syntax errors for which a correct declaration node cannot be
955         // created.
956         //
957         BadDecl struct {
958                 From, To token.Pos // position range of bad declaration
959         }
960
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.
964         //
965         // Relationship between Tok value and Specs element type:
966         //
967         //      token.IMPORT  *ImportSpec
968         //      token.CONST   *ValueSpec
969         //      token.TYPE    *TypeSpec
970         //      token.VAR     *ValueSpec
971         //
972         GenDecl struct {
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
977                 Specs  []Spec
978                 Rparen token.Pos // position of ')', if any
979         }
980
981         // A FuncDecl node represents a function declaration.
982         FuncDecl struct {
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
988         }
989 )
990
991 // Pos and End implementations for declaration nodes.
992
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() }
996
997 func (d *BadDecl) End() token.Pos { return d.To }
998 func (d *GenDecl) End() token.Pos {
999         if d.Rparen.IsValid() {
1000                 return d.Rparen + 1
1001         }
1002         return d.Specs[0].End()
1003 }
1004 func (d *FuncDecl) End() token.Pos {
1005         if d.Body != nil {
1006                 return d.Body.End()
1007         }
1008         return d.Type.End()
1009 }
1010
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() {}
1016
1017 // ----------------------------------------------------------------------------
1018 // Files and packages
1019
1020 // A File node represents a Go source file.
1021 //
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.
1025 //
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.
1033 //
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).
1038 type File struct {
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
1043
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
1050 }
1051
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 }
1055
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()
1061         }
1062         return f.Name.End()
1063 }
1064
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
1072 }
1073
1074 func (p *Package) Pos() token.Pos { return token.NoPos }
1075 func (p *Package) End() token.Pos { return token.NoPos }
1076
1077 // IsGenerated reports whether the file was generated by a program,
1078 // not handwritten, by detecting the special comment described
1079 // at https://go.dev/s/generatedcode.
1080 //
1081 // The syntax tree must have been parsed with the ParseComments flag.
1082 // Example:
1083 //
1084 //      f, err := parser.ParseFile(fset, filename, src, parser.ParseComments|parser.PackageClauseOnly)
1085 //      if err != nil { ... }
1086 //      gen := ast.IsGenerated(f)
1087 func IsGenerated(file *File) bool {
1088         _, ok := generator(file)
1089         return ok
1090 }
1091
1092 func generator(file *File) (string, bool) {
1093         for _, group := range file.Comments {
1094                 for _, comment := range group.List {
1095                         if comment.Pos() > file.Package {
1096                                 break // after package declaration
1097                         }
1098                         // opt: check Contains first to avoid unnecessary array allocation in Split.
1099                         const prefix = "// Code generated "
1100                         if strings.Contains(comment.Text, prefix) {
1101                                 for _, line := range strings.Split(comment.Text, "\n") {
1102                                         if rest, ok := strings.CutPrefix(line, prefix); ok {
1103                                                 if gen, ok := strings.CutSuffix(rest, " DO NOT EDIT."); ok {
1104                                                         return gen, true
1105                                                 }
1106                                         }
1107                                 }
1108                         }
1109                 }
1110         }
1111         return "", false
1112 }