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