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