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