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 BasicLit struct {
303 ValuePos token.Pos
304 Kind token.Token
305 Value string
306 }
307
308
309 FuncLit struct {
310 Type *FuncType
311 Body *BlockStmt
312 }
313
314
315 CompositeLit struct {
316 Type Expr
317 Lbrace token.Pos
318 Elts []Expr
319 Rbrace token.Pos
320 Incomplete bool
321 }
322
323
324 ParenExpr struct {
325 Lparen token.Pos
326 X Expr
327 Rparen token.Pos
328 }
329
330
331 SelectorExpr struct {
332 X Expr
333 Sel *Ident
334 }
335
336
337 IndexExpr struct {
338 X Expr
339 Lbrack token.Pos
340 Index Expr
341 Rbrack token.Pos
342 }
343
344
345
346 IndexListExpr struct {
347 X Expr
348 Lbrack token.Pos
349 Indices []Expr
350 Rbrack token.Pos
351 }
352
353
354 SliceExpr struct {
355 X Expr
356 Lbrack token.Pos
357 Low Expr
358 High Expr
359 Max Expr
360 Slice3 bool
361 Rbrack token.Pos
362 }
363
364
365
366
367 TypeAssertExpr struct {
368 X Expr
369 Lparen token.Pos
370 Type Expr
371 Rparen token.Pos
372 }
373
374
375 CallExpr struct {
376 Fun Expr
377 Lparen token.Pos
378 Args []Expr
379 Ellipsis token.Pos
380 Rparen token.Pos
381 }
382
383
384
385
386 StarExpr struct {
387 Star token.Pos
388 X Expr
389 }
390
391
392
393
394 UnaryExpr struct {
395 OpPos token.Pos
396 Op token.Token
397 X Expr
398 }
399
400
401 BinaryExpr struct {
402 X Expr
403 OpPos token.Pos
404 Op token.Token
405 Y Expr
406 }
407
408
409
410
411 KeyValueExpr struct {
412 Key Expr
413 Colon token.Pos
414 Value Expr
415 }
416 )
417
418
419
420 type ChanDir int
421
422 const (
423 SEND ChanDir = 1 << iota
424 RECV
425 )
426
427
428
429
430 type (
431
432 ArrayType struct {
433 Lbrack token.Pos
434 Len Expr
435 Elt Expr
436 }
437
438
439 StructType struct {
440 Struct token.Pos
441 Fields *FieldList
442 Incomplete bool
443 }
444
445
446
447
448 FuncType struct {
449 Func token.Pos
450 TypeParams *FieldList
451 Params *FieldList
452 Results *FieldList
453 }
454
455
456 InterfaceType struct {
457 Interface token.Pos
458 Methods *FieldList
459 Incomplete bool
460 }
461
462
463 MapType struct {
464 Map token.Pos
465 Key Expr
466 Value Expr
467 }
468
469
470 ChanType struct {
471 Begin token.Pos
472 Arrow token.Pos
473 Dir ChanDir
474 Value Expr
475 }
476 )
477
478
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 {
506 return x.Func
507 }
508 return x.Params.Pos()
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
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
549
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
577
578
579
580 func NewIdent(name string) *Ident { return &Ident{token.NoPos, name, nil} }
581
582
583 func IsExported(name string) bool { return token.IsExported(name) }
584
585
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
597
598
599
600 type (
601
602
603
604
605 BadStmt struct {
606 From, To token.Pos
607 }
608
609
610 DeclStmt struct {
611 Decl Decl
612 }
613
614
615
616
617
618 EmptyStmt struct {
619 Semicolon token.Pos
620 Implicit bool
621 }
622
623
624 LabeledStmt struct {
625 Label *Ident
626 Colon token.Pos
627 Stmt Stmt
628 }
629
630
631
632
633 ExprStmt struct {
634 X Expr
635 }
636
637
638 SendStmt struct {
639 Chan Expr
640 Arrow token.Pos
641 Value Expr
642 }
643
644
645 IncDecStmt struct {
646 X Expr
647 TokPos token.Pos
648 Tok token.Token
649 }
650
651
652
653
654 AssignStmt struct {
655 Lhs []Expr
656 TokPos token.Pos
657 Tok token.Token
658 Rhs []Expr
659 }
660
661
662 GoStmt struct {
663 Go token.Pos
664 Call *CallExpr
665 }
666
667
668 DeferStmt struct {
669 Defer token.Pos
670 Call *CallExpr
671 }
672
673
674 ReturnStmt struct {
675 Return token.Pos
676 Results []Expr
677 }
678
679
680
681
682 BranchStmt struct {
683 TokPos token.Pos
684 Tok token.Token
685 Label *Ident
686 }
687
688
689 BlockStmt struct {
690 Lbrace token.Pos
691 List []Stmt
692 Rbrace token.Pos
693 }
694
695
696 IfStmt struct {
697 If token.Pos
698 Init Stmt
699 Cond Expr
700 Body *BlockStmt
701 Else Stmt
702 }
703
704
705 CaseClause struct {
706 Case token.Pos
707 List []Expr
708 Colon token.Pos
709 Body []Stmt
710 }
711
712
713 SwitchStmt struct {
714 Switch token.Pos
715 Init Stmt
716 Tag Expr
717 Body *BlockStmt
718 }
719
720
721 TypeSwitchStmt struct {
722 Switch token.Pos
723 Init Stmt
724 Assign Stmt
725 Body *BlockStmt
726 }
727
728
729 CommClause struct {
730 Case token.Pos
731 Comm Stmt
732 Colon token.Pos
733 Body []Stmt
734 }
735
736
737 SelectStmt struct {
738 Select token.Pos
739 Body *BlockStmt
740 }
741
742
743 ForStmt struct {
744 For token.Pos
745 Init Stmt
746 Cond Expr
747 Post Stmt
748 Body *BlockStmt
749 }
750
751
752 RangeStmt struct {
753 For token.Pos
754 Key, Value Expr
755 TokPos token.Pos
756 Tok token.Token
757 Range token.Pos
758 X Expr
759 Body *BlockStmt
760 }
761 )
762
763
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
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
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
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
850
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
875
876
877
878 type (
879
880 Spec interface {
881 Node
882 specNode()
883 }
884
885
886 ImportSpec struct {
887 Doc *CommentGroup
888 Name *Ident
889 Path *BasicLit
890 Comment *CommentGroup
891 EndPos token.Pos
892 }
893
894
895
896
897 ValueSpec struct {
898 Doc *CommentGroup
899 Names []*Ident
900 Type Expr
901 Values []Expr
902 Comment *CommentGroup
903 }
904
905
906 TypeSpec struct {
907 Doc *CommentGroup
908 Name *Ident
909 TypeParams *FieldList
910 Assign token.Pos
911 Type Expr
912 Comment *CommentGroup
913 }
914 )
915
916
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
946
947 func (*ImportSpec) specNode() {}
948 func (*ValueSpec) specNode() {}
949 func (*TypeSpec) specNode() {}
950
951
952 type (
953
954
955
956
957 BadDecl struct {
958 From, To token.Pos
959 }
960
961
962
963
964
965
966
967
968
969
970
971
972 GenDecl struct {
973 Doc *CommentGroup
974 TokPos token.Pos
975 Tok token.Token
976 Lparen token.Pos
977 Specs []Spec
978 Rparen token.Pos
979 }
980
981
982 FuncDecl struct {
983 Doc *CommentGroup
984 Recv *FieldList
985 Name *Ident
986 Type *FuncType
987 Body *BlockStmt
988 }
989 )
990
991
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
1012
1013 func (*BadDecl) declNode() {}
1014 func (*GenDecl) declNode() {}
1015 func (*FuncDecl) declNode() {}
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041 type File struct {
1042 Doc *CommentGroup
1043 Package token.Pos
1044 Name *Ident
1045 Decls []Decl
1046
1047 FileStart, FileEnd token.Pos
1048 Scope *Scope
1049 Imports []*ImportSpec
1050 Unresolved []*Ident
1051 Comments []*CommentGroup
1052 GoVersion string
1053 }
1054
1055
1056
1057 func (f *File) Pos() token.Pos { return f.Package }
1058
1059
1060
1061 func (f *File) End() token.Pos {
1062 if n := len(f.Decls); n > 0 {
1063 return f.Decls[n-1].End()
1064 }
1065 return f.Name.End()
1066 }
1067
1068
1069
1070
1071
1072 type Package struct {
1073 Name string
1074 Scope *Scope
1075 Imports map[string]*Object
1076 Files map[string]*File
1077 }
1078
1079 func (p *Package) Pos() token.Pos { return token.NoPos }
1080 func (p *Package) End() token.Pos { return token.NoPos }
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092 func IsGenerated(file *File) bool {
1093 _, ok := generator(file)
1094 return ok
1095 }
1096
1097 func generator(file *File) (string, bool) {
1098 for _, group := range file.Comments {
1099 for _, comment := range group.List {
1100 if comment.Pos() > file.Package {
1101 break
1102 }
1103
1104 const prefix = "// Code generated "
1105 if strings.Contains(comment.Text, prefix) {
1106 for _, line := range strings.Split(comment.Text, "\n") {
1107 if rest, ok := strings.CutPrefix(line, prefix); ok {
1108 if gen, ok := strings.CutSuffix(rest, " DO NOT EDIT."); ok {
1109 return gen, true
1110 }
1111 }
1112 }
1113 }
1114 }
1115 }
1116 return "", false
1117 }
1118
1119
1120 func Unparen(e Expr) Expr {
1121 for {
1122 paren, ok := e.(*ParenExpr)
1123 if !ok {
1124 return e
1125 }
1126 e = paren.X
1127 }
1128 }
1129
View as plain text