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