...
Source file
src/go/ast/ast.go
Documentation: go/ast
1
2
3
4
5
6
7
8 package ast
9
10 import (
11 "go/token"
12 "strings"
13 "unicode"
14 "unicode/utf8"
15 )
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 type Node interface {
36 Pos() token.Pos
37 End() token.Pos
38 }
39
40
41 type Expr interface {
42 Node
43 exprNode()
44 }
45
46
47 type Stmt interface {
48 Node
49 stmtNode()
50 }
51
52
53 type Decl interface {
54 Node
55 declNode()
56 }
57
58
59
60
61
62 type Comment struct {
63 Slash token.Pos
64 Text string
65 }
66
67 func (c *Comment) Pos() token.Pos { return c.Slash }
68 func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) }
69
70
71
72
73 type CommentGroup struct {
74 List []*Comment
75 }
76
77 func (g *CommentGroup) Pos() token.Pos { return g.List[0].Pos() }
78 func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() }
79
80 func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }
81
82 func stripTrailingWhitespace(s string) string {
83 i := len(s)
84 for i > 0 && isWhitespace(s[i-1]) {
85 i--
86 }
87 return s[0:i]
88 }
89
90
91
92
93
94
95
96 func (g *CommentGroup) Text() string {
97 if g == nil {
98 return ""
99 }
100 comments := make([]string, len(g.List))
101 for i, c := range g.List {
102 comments[i] = c.Text
103 }
104
105 lines := make([]string, 0, 10)
106 for _, c := range comments {
107
108
109 switch c[1] {
110 case '/':
111
112 c = c[2:]
113
114 if len(c) > 0 && c[0] == ' ' {
115 c = c[1:]
116 }
117 case '*':
118
119 c = c[2 : len(c)-2]
120 }
121
122
123 cl := strings.Split(c, "\n")
124
125
126 for _, l := range cl {
127 lines = append(lines, stripTrailingWhitespace(l))
128 }
129 }
130
131
132
133 n := 0
134 for _, line := range lines {
135 if line != "" || n > 0 && lines[n-1] != "" {
136 lines[n] = line
137 n++
138 }
139 }
140 lines = lines[0:n]
141
142
143 if n > 0 && lines[n-1] != "" {
144 lines = append(lines, "")
145 }
146
147 return strings.Join(lines, "\n")
148 }
149
150
151
152
153
154
155
156
157
158
159 type Field struct {
160 Doc *CommentGroup
161 Names []*Ident
162 Type Expr
163 Tag *BasicLit
164 Comment *CommentGroup
165 }
166
167 func (f *Field) Pos() token.Pos {
168 if len(f.Names) > 0 {
169 return f.Names[0].Pos()
170 }
171 return f.Type.Pos()
172 }
173
174 func (f *Field) End() token.Pos {
175 if f.Tag != nil {
176 return f.Tag.End()
177 }
178 return f.Type.End()
179 }
180
181
182 type FieldList struct {
183 Opening token.Pos
184 List []*Field
185 Closing token.Pos
186 }
187
188 func (f *FieldList) Pos() token.Pos {
189 if f.Opening.IsValid() {
190 return f.Opening
191 }
192
193
194 if len(f.List) > 0 {
195 return f.List[0].Pos()
196 }
197 return token.NoPos
198 }
199
200 func (f *FieldList) End() token.Pos {
201 if f.Closing.IsValid() {
202 return f.Closing + 1
203 }
204
205
206 if n := len(f.List); n > 0 {
207 return f.List[n-1].End()
208 }
209 return token.NoPos
210 }
211
212
213 func (f *FieldList) NumFields() int {
214 n := 0
215 if f != nil {
216 for _, g := range f.List {
217 m := len(g.Names)
218 if m == 0 {
219 m = 1
220 }
221 n += m
222 }
223 }
224 return n
225 }
226
227
228
229
230 type (
231
232
233
234
235 BadExpr struct {
236 From, To token.Pos
237 }
238
239
240 Ident struct {
241 NamePos token.Pos
242 Name string
243 Obj *Object
244 }
245
246
247
248
249 Ellipsis struct {
250 Ellipsis token.Pos
251 Elt Expr
252 }
253
254
255 BasicLit struct {
256 ValuePos token.Pos
257 Kind token.Token
258 Value string
259 }
260
261
262 FuncLit struct {
263 Type *FuncType
264 Body *BlockStmt
265 }
266
267
268 CompositeLit struct {
269 Type Expr
270 Lbrace token.Pos
271 Elts []Expr
272 Rbrace token.Pos
273 Incomplete bool
274 }
275
276
277 ParenExpr struct {
278 Lparen token.Pos
279 X Expr
280 Rparen token.Pos
281 }
282
283
284 SelectorExpr struct {
285 X Expr
286 Sel *Ident
287 }
288
289
290 IndexExpr struct {
291 X Expr
292 Lbrack token.Pos
293 Index Expr
294 Rbrack token.Pos
295 }
296
297
298 SliceExpr struct {
299 X Expr
300 Lbrack token.Pos
301 Low Expr
302 High Expr
303 Max Expr
304 Slice3 bool
305 Rbrack token.Pos
306 }
307
308
309
310
311 TypeAssertExpr struct {
312 X Expr
313 Lparen token.Pos
314 Type Expr
315 Rparen token.Pos
316 }
317
318
319 CallExpr struct {
320 Fun Expr
321 Lparen token.Pos
322 Args []Expr
323 Ellipsis token.Pos
324 Rparen token.Pos
325 }
326
327
328
329
330 StarExpr struct {
331 Star token.Pos
332 X Expr
333 }
334
335
336
337
338 UnaryExpr struct {
339 OpPos token.Pos
340 Op token.Token
341 X Expr
342 }
343
344
345 BinaryExpr struct {
346 X Expr
347 OpPos token.Pos
348 Op token.Token
349 Y Expr
350 }
351
352
353
354
355 KeyValueExpr struct {
356 Key Expr
357 Colon token.Pos
358 Value Expr
359 }
360 )
361
362
363
364
365 type ChanDir int
366
367 const (
368 SEND ChanDir = 1 << iota
369 RECV
370 )
371
372
373
374
375
376 type (
377
378 ArrayType struct {
379 Lbrack token.Pos
380 Len Expr
381 Elt Expr
382 }
383
384
385 StructType struct {
386 Struct token.Pos
387 Fields *FieldList
388 Incomplete bool
389 }
390
391
392
393
394 FuncType struct {
395 Func token.Pos
396 Params *FieldList
397 Results *FieldList
398 }
399
400
401 InterfaceType struct {
402 Interface token.Pos
403 Methods *FieldList
404 Incomplete bool
405 }
406
407
408 MapType struct {
409 Map token.Pos
410 Key Expr
411 Value Expr
412 }
413
414
415 ChanType struct {
416 Begin token.Pos
417 Arrow token.Pos
418 Dir ChanDir
419 Value Expr
420 }
421 )
422
423
424
425 func (x *BadExpr) Pos() token.Pos { return x.From }
426 func (x *Ident) Pos() token.Pos { return x.NamePos }
427 func (x *Ellipsis) Pos() token.Pos { return x.Ellipsis }
428 func (x *BasicLit) Pos() token.Pos { return x.ValuePos }
429 func (x *FuncLit) Pos() token.Pos { return x.Type.Pos() }
430 func (x *CompositeLit) Pos() token.Pos {
431 if x.Type != nil {
432 return x.Type.Pos()
433 }
434 return x.Lbrace
435 }
436 func (x *ParenExpr) Pos() token.Pos { return x.Lparen }
437 func (x *SelectorExpr) Pos() token.Pos { return x.X.Pos() }
438 func (x *IndexExpr) Pos() token.Pos { return x.X.Pos() }
439 func (x *SliceExpr) Pos() token.Pos { return x.X.Pos() }
440 func (x *TypeAssertExpr) Pos() token.Pos { return x.X.Pos() }
441 func (x *CallExpr) Pos() token.Pos { return x.Fun.Pos() }
442 func (x *StarExpr) Pos() token.Pos { return x.Star }
443 func (x *UnaryExpr) Pos() token.Pos { return x.OpPos }
444 func (x *BinaryExpr) Pos() token.Pos { return x.X.Pos() }
445 func (x *KeyValueExpr) Pos() token.Pos { return x.Key.Pos() }
446 func (x *ArrayType) Pos() token.Pos { return x.Lbrack }
447 func (x *StructType) Pos() token.Pos { return x.Struct }
448 func (x *FuncType) Pos() token.Pos {
449 if x.Func.IsValid() || x.Params == nil {
450 return x.Func
451 }
452 return x.Params.Pos()
453 }
454 func (x *InterfaceType) Pos() token.Pos { return x.Interface }
455 func (x *MapType) Pos() token.Pos { return x.Map }
456 func (x *ChanType) Pos() token.Pos { return x.Begin }
457
458 func (x *BadExpr) End() token.Pos { return x.To }
459 func (x *Ident) End() token.Pos { return token.Pos(int(x.NamePos) + len(x.Name)) }
460 func (x *Ellipsis) End() token.Pos {
461 if x.Elt != nil {
462 return x.Elt.End()
463 }
464 return x.Ellipsis + 3
465 }
466 func (x *BasicLit) End() token.Pos { return token.Pos(int(x.ValuePos) + len(x.Value)) }
467 func (x *FuncLit) End() token.Pos { return x.Body.End() }
468 func (x *CompositeLit) End() token.Pos { return x.Rbrace + 1 }
469 func (x *ParenExpr) End() token.Pos { return x.Rparen + 1 }
470 func (x *SelectorExpr) End() token.Pos { return x.Sel.End() }
471 func (x *IndexExpr) End() token.Pos { return x.Rbrack + 1 }
472 func (x *SliceExpr) End() token.Pos { return x.Rbrack + 1 }
473 func (x *TypeAssertExpr) End() token.Pos { return x.Rparen + 1 }
474 func (x *CallExpr) End() token.Pos { return x.Rparen + 1 }
475 func (x *StarExpr) End() token.Pos { return x.X.End() }
476 func (x *UnaryExpr) End() token.Pos { return x.X.End() }
477 func (x *BinaryExpr) End() token.Pos { return x.Y.End() }
478 func (x *KeyValueExpr) End() token.Pos { return x.Value.End() }
479 func (x *ArrayType) End() token.Pos { return x.Elt.End() }
480 func (x *StructType) End() token.Pos { return x.Fields.End() }
481 func (x *FuncType) End() token.Pos {
482 if x.Results != nil {
483 return x.Results.End()
484 }
485 return x.Params.End()
486 }
487 func (x *InterfaceType) End() token.Pos { return x.Methods.End() }
488 func (x *MapType) End() token.Pos { return x.Value.End() }
489 func (x *ChanType) End() token.Pos { return x.Value.End() }
490
491
492
493
494 func (*BadExpr) exprNode() {}
495 func (*Ident) exprNode() {}
496 func (*Ellipsis) exprNode() {}
497 func (*BasicLit) exprNode() {}
498 func (*FuncLit) exprNode() {}
499 func (*CompositeLit) exprNode() {}
500 func (*ParenExpr) exprNode() {}
501 func (*SelectorExpr) exprNode() {}
502 func (*IndexExpr) exprNode() {}
503 func (*SliceExpr) exprNode() {}
504 func (*TypeAssertExpr) exprNode() {}
505 func (*CallExpr) exprNode() {}
506 func (*StarExpr) exprNode() {}
507 func (*UnaryExpr) exprNode() {}
508 func (*BinaryExpr) exprNode() {}
509 func (*KeyValueExpr) exprNode() {}
510
511 func (*ArrayType) exprNode() {}
512 func (*StructType) exprNode() {}
513 func (*FuncType) exprNode() {}
514 func (*InterfaceType) exprNode() {}
515 func (*MapType) exprNode() {}
516 func (*ChanType) exprNode() {}
517
518
519
520
521
522
523
524 func NewIdent(name string) *Ident { return &Ident{token.NoPos, name, nil} }
525
526
527
528
529 func IsExported(name string) bool {
530 ch, _ := utf8.DecodeRuneInString(name)
531 return unicode.IsUpper(ch)
532 }
533
534
535
536
537 func (id *Ident) IsExported() bool { return IsExported(id.Name) }
538
539 func (id *Ident) String() string {
540 if id != nil {
541 return id.Name
542 }
543 return "<nil>"
544 }
545
546
547
548
549
550
551
552 type (
553
554
555
556
557 BadStmt struct {
558 From, To token.Pos
559 }
560
561
562 DeclStmt struct {
563 Decl Decl
564 }
565
566
567
568
569
570 EmptyStmt struct {
571 Semicolon token.Pos
572 Implicit bool
573 }
574
575
576 LabeledStmt struct {
577 Label *Ident
578 Colon token.Pos
579 Stmt Stmt
580 }
581
582
583
584
585 ExprStmt struct {
586 X Expr
587 }
588
589
590 SendStmt struct {
591 Chan Expr
592 Arrow token.Pos
593 Value Expr
594 }
595
596
597 IncDecStmt struct {
598 X Expr
599 TokPos token.Pos
600 Tok token.Token
601 }
602
603
604
605
606 AssignStmt struct {
607 Lhs []Expr
608 TokPos token.Pos
609 Tok token.Token
610 Rhs []Expr
611 }
612
613
614 GoStmt struct {
615 Go token.Pos
616 Call *CallExpr
617 }
618
619
620 DeferStmt struct {
621 Defer token.Pos
622 Call *CallExpr
623 }
624
625
626 ReturnStmt struct {
627 Return token.Pos
628 Results []Expr
629 }
630
631
632
633
634 BranchStmt struct {
635 TokPos token.Pos
636 Tok token.Token
637 Label *Ident
638 }
639
640
641 BlockStmt struct {
642 Lbrace token.Pos
643 List []Stmt
644 Rbrace token.Pos
645 }
646
647
648 IfStmt struct {
649 If token.Pos
650 Init Stmt
651 Cond Expr
652 Body *BlockStmt
653 Else Stmt
654 }
655
656
657 CaseClause struct {
658 Case token.Pos
659 List []Expr
660 Colon token.Pos
661 Body []Stmt
662 }
663
664
665 SwitchStmt struct {
666 Switch token.Pos
667 Init Stmt
668 Tag Expr
669 Body *BlockStmt
670 }
671
672
673 TypeSwitchStmt struct {
674 Switch token.Pos
675 Init Stmt
676 Assign Stmt
677 Body *BlockStmt
678 }
679
680
681 CommClause struct {
682 Case token.Pos
683 Comm Stmt
684 Colon token.Pos
685 Body []Stmt
686 }
687
688
689 SelectStmt struct {
690 Select token.Pos
691 Body *BlockStmt
692 }
693
694
695 ForStmt struct {
696 For token.Pos
697 Init Stmt
698 Cond Expr
699 Post Stmt
700 Body *BlockStmt
701 }
702
703
704 RangeStmt struct {
705 For token.Pos
706 Key, Value Expr
707 TokPos token.Pos
708 Tok token.Token
709 X Expr
710 Body *BlockStmt
711 }
712 )
713
714
715
716 func (s *BadStmt) Pos() token.Pos { return s.From }
717 func (s *DeclStmt) Pos() token.Pos { return s.Decl.Pos() }
718 func (s *EmptyStmt) Pos() token.Pos { return s.Semicolon }
719 func (s *LabeledStmt) Pos() token.Pos { return s.Label.Pos() }
720 func (s *ExprStmt) Pos() token.Pos { return s.X.Pos() }
721 func (s *SendStmt) Pos() token.Pos { return s.Chan.Pos() }
722 func (s *IncDecStmt) Pos() token.Pos { return s.X.Pos() }
723 func (s *AssignStmt) Pos() token.Pos { return s.Lhs[0].Pos() }
724 func (s *GoStmt) Pos() token.Pos { return s.Go }
725 func (s *DeferStmt) Pos() token.Pos { return s.Defer }
726 func (s *ReturnStmt) Pos() token.Pos { return s.Return }
727 func (s *BranchStmt) Pos() token.Pos { return s.TokPos }
728 func (s *BlockStmt) Pos() token.Pos { return s.Lbrace }
729 func (s *IfStmt) Pos() token.Pos { return s.If }
730 func (s *CaseClause) Pos() token.Pos { return s.Case }
731 func (s *SwitchStmt) Pos() token.Pos { return s.Switch }
732 func (s *TypeSwitchStmt) Pos() token.Pos { return s.Switch }
733 func (s *CommClause) Pos() token.Pos { return s.Case }
734 func (s *SelectStmt) Pos() token.Pos { return s.Select }
735 func (s *ForStmt) Pos() token.Pos { return s.For }
736 func (s *RangeStmt) Pos() token.Pos { return s.For }
737
738 func (s *BadStmt) End() token.Pos { return s.To }
739 func (s *DeclStmt) End() token.Pos { return s.Decl.End() }
740 func (s *EmptyStmt) End() token.Pos {
741 if s.Implicit {
742 return s.Semicolon
743 }
744 return s.Semicolon + 1
745 }
746 func (s *LabeledStmt) End() token.Pos { return s.Stmt.End() }
747 func (s *ExprStmt) End() token.Pos { return s.X.End() }
748 func (s *SendStmt) End() token.Pos { return s.Value.End() }
749 func (s *IncDecStmt) End() token.Pos {
750 return s.TokPos + 2
751 }
752 func (s *AssignStmt) End() token.Pos { return s.Rhs[len(s.Rhs)-1].End() }
753 func (s *GoStmt) End() token.Pos { return s.Call.End() }
754 func (s *DeferStmt) End() token.Pos { return s.Call.End() }
755 func (s *ReturnStmt) End() token.Pos {
756 if n := len(s.Results); n > 0 {
757 return s.Results[n-1].End()
758 }
759 return s.Return + 6
760 }
761 func (s *BranchStmt) End() token.Pos {
762 if s.Label != nil {
763 return s.Label.End()
764 }
765 return token.Pos(int(s.TokPos) + len(s.Tok.String()))
766 }
767 func (s *BlockStmt) End() token.Pos { return s.Rbrace + 1 }
768 func (s *IfStmt) End() token.Pos {
769 if s.Else != nil {
770 return s.Else.End()
771 }
772 return s.Body.End()
773 }
774 func (s *CaseClause) End() token.Pos {
775 if n := len(s.Body); n > 0 {
776 return s.Body[n-1].End()
777 }
778 return s.Colon + 1
779 }
780 func (s *SwitchStmt) End() token.Pos { return s.Body.End() }
781 func (s *TypeSwitchStmt) End() token.Pos { return s.Body.End() }
782 func (s *CommClause) End() token.Pos {
783 if n := len(s.Body); n > 0 {
784 return s.Body[n-1].End()
785 }
786 return s.Colon + 1
787 }
788 func (s *SelectStmt) End() token.Pos { return s.Body.End() }
789 func (s *ForStmt) End() token.Pos { return s.Body.End() }
790 func (s *RangeStmt) End() token.Pos { return s.Body.End() }
791
792
793
794
795 func (*BadStmt) stmtNode() {}
796 func (*DeclStmt) stmtNode() {}
797 func (*EmptyStmt) stmtNode() {}
798 func (*LabeledStmt) stmtNode() {}
799 func (*ExprStmt) stmtNode() {}
800 func (*SendStmt) stmtNode() {}
801 func (*IncDecStmt) stmtNode() {}
802 func (*AssignStmt) stmtNode() {}
803 func (*GoStmt) stmtNode() {}
804 func (*DeferStmt) stmtNode() {}
805 func (*ReturnStmt) stmtNode() {}
806 func (*BranchStmt) stmtNode() {}
807 func (*BlockStmt) stmtNode() {}
808 func (*IfStmt) stmtNode() {}
809 func (*CaseClause) stmtNode() {}
810 func (*SwitchStmt) stmtNode() {}
811 func (*TypeSwitchStmt) stmtNode() {}
812 func (*CommClause) stmtNode() {}
813 func (*SelectStmt) stmtNode() {}
814 func (*ForStmt) stmtNode() {}
815 func (*RangeStmt) stmtNode() {}
816
817
818
819
820
821
822
823 type (
824
825 Spec interface {
826 Node
827 specNode()
828 }
829
830
831 ImportSpec struct {
832 Doc *CommentGroup
833 Name *Ident
834 Path *BasicLit
835 Comment *CommentGroup
836 EndPos token.Pos
837 }
838
839
840
841
842 ValueSpec struct {
843 Doc *CommentGroup
844 Names []*Ident
845 Type Expr
846 Values []Expr
847 Comment *CommentGroup
848 }
849
850
851 TypeSpec struct {
852 Doc *CommentGroup
853 Name *Ident
854 Assign token.Pos
855 Type Expr
856 Comment *CommentGroup
857 }
858 )
859
860
861
862 func (s *ImportSpec) Pos() token.Pos {
863 if s.Name != nil {
864 return s.Name.Pos()
865 }
866 return s.Path.Pos()
867 }
868 func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() }
869 func (s *TypeSpec) Pos() token.Pos { return s.Name.Pos() }
870
871 func (s *ImportSpec) End() token.Pos {
872 if s.EndPos != 0 {
873 return s.EndPos
874 }
875 return s.Path.End()
876 }
877
878 func (s *ValueSpec) End() token.Pos {
879 if n := len(s.Values); n > 0 {
880 return s.Values[n-1].End()
881 }
882 if s.Type != nil {
883 return s.Type.End()
884 }
885 return s.Names[len(s.Names)-1].End()
886 }
887 func (s *TypeSpec) End() token.Pos { return s.Type.End() }
888
889
890
891
892 func (*ImportSpec) specNode() {}
893 func (*ValueSpec) specNode() {}
894 func (*TypeSpec) specNode() {}
895
896
897
898 type (
899
900
901
902
903 BadDecl struct {
904 From, To token.Pos
905 }
906
907
908
909
910
911
912
913
914
915
916
917
918 GenDecl struct {
919 Doc *CommentGroup
920 TokPos token.Pos
921 Tok token.Token
922 Lparen token.Pos
923 Specs []Spec
924 Rparen token.Pos
925 }
926
927
928 FuncDecl struct {
929 Doc *CommentGroup
930 Recv *FieldList
931 Name *Ident
932 Type *FuncType
933 Body *BlockStmt
934 }
935 )
936
937
938
939 func (d *BadDecl) Pos() token.Pos { return d.From }
940 func (d *GenDecl) Pos() token.Pos { return d.TokPos }
941 func (d *FuncDecl) Pos() token.Pos { return d.Type.Pos() }
942
943 func (d *BadDecl) End() token.Pos { return d.To }
944 func (d *GenDecl) End() token.Pos {
945 if d.Rparen.IsValid() {
946 return d.Rparen + 1
947 }
948 return d.Specs[0].End()
949 }
950 func (d *FuncDecl) End() token.Pos {
951 if d.Body != nil {
952 return d.Body.End()
953 }
954 return d.Type.End()
955 }
956
957
958
959
960 func (*BadDecl) declNode() {}
961 func (*GenDecl) declNode() {}
962 func (*FuncDecl) declNode() {}
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986 type File struct {
987 Doc *CommentGroup
988 Package token.Pos
989 Name *Ident
990 Decls []Decl
991 Scope *Scope
992 Imports []*ImportSpec
993 Unresolved []*Ident
994 Comments []*CommentGroup
995 }
996
997 func (f *File) Pos() token.Pos { return f.Package }
998 func (f *File) End() token.Pos {
999 if n := len(f.Decls); n > 0 {
1000 return f.Decls[n-1].End()
1001 }
1002 return f.Name.End()
1003 }
1004
1005
1006
1007
1008 type Package struct {
1009 Name string
1010 Scope *Scope
1011 Imports map[string]*Object
1012 Files map[string]*File
1013 }
1014
1015 func (p *Package) Pos() token.Pos { return token.NoPos }
1016 func (p *Package) End() token.Pos { return token.NoPos }
1017
View as plain text