1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package ast
18
19 import (
20 "fmt"
21 "strings"
22
23 "cuelang.org/go/cue/literal"
24 "cuelang.org/go/cue/token"
25 )
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 type Node interface {
44 Pos() token.Pos
45 End() token.Pos
46
47
48
49 pos() *token.Pos
50
51
52 Comments() []*CommentGroup
53
54
55 AddComment(*CommentGroup)
56 commentInfo() *comments
57 }
58
59
60 func Name(n Node) string {
61 s := fmt.Sprintf("%T", n)
62 return strings.ToLower(s[strings.Index(s, "ast.")+4:])
63 }
64
65 func getPos(n Node) token.Pos {
66 p := n.pos()
67 if p == nil {
68 return token.NoPos
69 }
70 return *p
71 }
72
73
74 func SetPos(n Node, p token.Pos) {
75 ptr := n.pos()
76 if ptr == nil {
77 return
78 }
79 *ptr = p
80 }
81
82
83
84
85 func SetRelPos(n Node, p token.RelPos) {
86 ptr := n.pos()
87 if ptr == nil {
88 return
89 }
90 pos := *ptr
91 *ptr = pos.WithRel(p)
92 }
93
94
95 type Expr interface {
96 Node
97 declNode()
98 exprNode()
99 }
100
101 type expr struct{ decl }
102
103 func (expr) exprNode() {}
104
105
106 type Decl interface {
107 Node
108 declNode()
109 }
110
111 type decl struct{}
112
113 func (decl) declNode() {}
114
115
116 type Label interface {
117 Node
118 labelNode()
119 }
120
121 type label struct{}
122
123 func (l label) labelNode() {}
124
125
126 type Clause interface {
127 Node
128 clauseNode()
129 }
130
131 type clause struct{}
132
133 func (clause) clauseNode() {}
134
135
136
137 type comments struct {
138 groups *[]*CommentGroup
139 }
140
141 func (c *comments) commentInfo() *comments { return c }
142
143 func (c *comments) Comments() []*CommentGroup {
144 if c.groups == nil {
145 return []*CommentGroup{}
146 }
147 return *c.groups
148 }
149
150
151
152
153 func (c *comments) AddComment(cg *CommentGroup) {
154 if cg == nil {
155 return
156 }
157 if c.groups == nil {
158 a := []*CommentGroup{cg}
159 c.groups = &a
160 return
161 }
162
163 *c.groups = append(*c.groups, cg)
164 a := *c.groups
165 for i := len(a) - 2; i >= 0 && a[i].Position > cg.Position; i-- {
166 a[i], a[i+1] = a[i+1], a[i]
167 }
168 }
169
170 func (c *comments) SetComments(cgs []*CommentGroup) {
171 if c.groups == nil {
172 a := cgs
173 c.groups = &a
174 return
175 }
176 *c.groups = cgs
177 }
178
179
180 type Comment struct {
181 Slash token.Pos
182 Text string
183 }
184
185 func (c *Comment) Comments() []*CommentGroup { return nil }
186 func (c *Comment) AddComment(*CommentGroup) {}
187 func (c *Comment) commentInfo() *comments { return nil }
188
189 func (c *Comment) Pos() token.Pos { return c.Slash }
190 func (c *Comment) pos() *token.Pos { return &c.Slash }
191 func (c *Comment) End() token.Pos { return c.Slash.Add(len(c.Text)) }
192
193
194
195 type CommentGroup struct {
196
197 Doc bool
198 Line bool
199
200
201
202
203
204 Position int8
205 List []*Comment
206
207 decl
208 }
209
210 func (g *CommentGroup) Pos() token.Pos { return getPos(g) }
211 func (g *CommentGroup) pos() *token.Pos { return g.List[0].pos() }
212 func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() }
213
214 func (g *CommentGroup) Comments() []*CommentGroup { return nil }
215 func (g *CommentGroup) AddComment(*CommentGroup) {}
216 func (g *CommentGroup) commentInfo() *comments { return nil }
217
218 func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }
219
220 func stripTrailingWhitespace(s string) string {
221 i := len(s)
222 for i > 0 && isWhitespace(s[i-1]) {
223 i--
224 }
225 return s[0:i]
226 }
227
228
229
230
231
232
233 func (g *CommentGroup) Text() string {
234 if g == nil {
235 return ""
236 }
237 comments := make([]string, len(g.List))
238 for i, c := range g.List {
239 comments[i] = c.Text
240 }
241
242 lines := make([]string, 0, 10)
243 for _, c := range comments {
244
245
246 switch c[1] {
247 case '/':
248
249 c = c[2:]
250
251 if len(c) > 0 && c[0] == ' ' {
252 c = c[1:]
253 }
254 case '*':
255
256 c = c[2 : len(c)-2]
257 }
258
259
260 cl := strings.Split(c, "\n")
261
262
263 for _, l := range cl {
264 lines = append(lines, stripTrailingWhitespace(l))
265 }
266 }
267
268
269
270 n := 0
271 for _, line := range lines {
272 if line != "" || n > 0 && lines[n-1] != "" {
273 lines[n] = line
274 n++
275 }
276 }
277 lines = lines[0:n]
278
279
280 if n > 0 && lines[n-1] != "" {
281 lines = append(lines, "")
282 }
283
284 return strings.Join(lines, "\n")
285 }
286
287
288 type Attribute struct {
289 At token.Pos
290 Text string
291
292 comments
293 decl
294 }
295
296 func (a *Attribute) Pos() token.Pos { return a.At }
297 func (a *Attribute) pos() *token.Pos { return &a.At }
298 func (a *Attribute) End() token.Pos { return a.At.Add(len(a.Text)) }
299
300 func (a *Attribute) Split() (key, body string) {
301 s := a.Text
302 p := strings.IndexByte(s, '(')
303 if p < 0 || !strings.HasPrefix(s, "@") || !strings.HasSuffix(s, ")") {
304 return "", ""
305 }
306 return a.Text[1:p], a.Text[p+1 : len(s)-1]
307 }
308
309
310 type Field struct {
311 Label Label
312 Optional token.Pos
313 Constraint token.Token
314
315
316 TokenPos token.Pos
317 Token token.Token
318
319 Value Expr
320
321 Attrs []*Attribute
322
323 comments
324 decl
325 }
326
327 func (d *Field) Pos() token.Pos { return d.Label.Pos() }
328 func (d *Field) pos() *token.Pos { return d.Label.pos() }
329 func (d *Field) End() token.Pos {
330 if len(d.Attrs) > 0 {
331 return d.Attrs[len(d.Attrs)-1].End()
332 }
333 return d.Value.End()
334 }
335
336
337
338
339
340 type Alias struct {
341 Ident *Ident
342 Equal token.Pos
343 Expr Expr
344
345 comments
346 clause
347 decl
348 expr
349 label
350 }
351
352 func (a *Alias) Pos() token.Pos { return a.Ident.Pos() }
353 func (a *Alias) pos() *token.Pos { return a.Ident.pos() }
354 func (a *Alias) End() token.Pos { return a.Expr.End() }
355
356
357 type Comprehension struct {
358 Clauses []Clause
359 Value Expr
360
361 comments
362 decl
363 expr
364 }
365
366 func (x *Comprehension) Pos() token.Pos { return getPos(x) }
367 func (x *Comprehension) pos() *token.Pos { return x.Clauses[0].pos() }
368 func (x *Comprehension) End() token.Pos {
369 return x.Value.End()
370 }
371
372
373
374
375
376
377
378
379
380
381
382 type BadExpr struct {
383 From, To token.Pos
384
385 comments
386 expr
387 }
388
389
390 type BottomLit struct {
391 Bottom token.Pos
392
393 comments
394 expr
395 }
396
397
398
399 type Ident struct {
400 NamePos token.Pos
401
402
403
404
405 Name string
406
407 Scope Node
408 Node Node
409
410 comments
411 label
412 expr
413 }
414
415
416 type BasicLit struct {
417 ValuePos token.Pos
418 Kind token.Token
419 Value string
420
421 comments
422 expr
423 label
424 }
425
426
427
428
429
430
431
432
433 func NewString(str string) *BasicLit {
434 str = literal.String.Quote(str)
435 return &BasicLit{Kind: token.STRING, ValuePos: token.NoPos, Value: str}
436 }
437
438
439
440 func NewNull() *BasicLit {
441 return &BasicLit{Kind: token.NULL, Value: "null"}
442 }
443
444
445
446
447 func NewLit(tok token.Token, s string) *BasicLit {
448 return &BasicLit{Kind: tok, Value: s}
449 }
450
451
452
453 func NewBool(b bool) *BasicLit {
454 x := &BasicLit{}
455 if b {
456 x.Kind = token.TRUE
457 x.Value = "true"
458 } else {
459 x.Kind = token.FALSE
460 x.Value = "false"
461 }
462 return x
463 }
464
465
466
467
468
469
470 type Interpolation struct {
471 Elts []Expr
472
473 comments
474 expr
475 label
476 }
477
478
479
480
481 type Func struct {
482 Func token.Pos
483 Args []Expr
484 Ret Expr
485
486 comments
487 expr
488 }
489
490
491 type StructLit struct {
492 Lbrace token.Pos
493 Elts []Decl
494 Rbrace token.Pos
495
496 comments
497 expr
498 }
499
500
501
502
503
504
505
506
507
508 func NewStruct(fields ...interface{}) *StructLit {
509 s := &StructLit{
510
511 Lbrace: token.NoSpace.Pos(),
512 }
513 for i := 0; i < len(fields); i++ {
514 var (
515 label Label
516 optional = token.NoPos
517 constraint = token.ILLEGAL
518 expr Expr
519 )
520
521 switch x := fields[i].(type) {
522 case *Field:
523 s.Elts = append(s.Elts, x)
524 continue
525 case *CommentGroup:
526 s.Elts = append(s.Elts, x)
527 continue
528 case *Ellipsis:
529 s.Elts = append(s.Elts, x)
530 continue
531 case *LetClause:
532 s.Elts = append(s.Elts, x)
533 continue
534 case *embedding:
535 s.Elts = append(s.Elts, (*EmbedDecl)(x))
536 continue
537 case Label:
538 label = x
539 case string:
540 label = NewString(x)
541 default:
542 panic(fmt.Sprintf("unsupported label type %T", x))
543 }
544
545 inner:
546 for i++; i < len(fields); i++ {
547 switch x := (fields[i]).(type) {
548 case Expr:
549 expr = x
550 break inner
551 case token.Token:
552 switch x {
553 case token.OPTION:
554 constraint = x
555 optional = token.Blank.Pos()
556 case token.NOT:
557 constraint = x
558 case token.COLON, token.ILLEGAL:
559 default:
560 panic(fmt.Sprintf("invalid token %s", x))
561 }
562 default:
563 panic(fmt.Sprintf("unsupported expression type %T", x))
564 }
565 }
566 if expr == nil {
567 panic("label not matched with expression")
568 }
569 s.Elts = append(s.Elts, &Field{
570 Label: label,
571 Optional: optional,
572 Constraint: constraint,
573 Value: expr,
574 })
575 }
576 return s
577 }
578
579
580 func Embed(x Expr) *embedding {
581 return (*embedding)(&EmbedDecl{Expr: x})
582 }
583
584 type embedding EmbedDecl
585
586
587 type ListLit struct {
588 Lbrack token.Pos
589
590
591 Elts []Expr
592 Rbrack token.Pos
593
594 comments
595 expr
596 label
597 }
598
599
600
601 func NewList(exprs ...Expr) *ListLit {
602 return &ListLit{Elts: exprs}
603 }
604
605 type Ellipsis struct {
606 Ellipsis token.Pos
607 Type Expr
608
609 comments
610 decl
611 expr
612 }
613
614
615 type ForClause struct {
616 For token.Pos
617 Key *Ident
618
619 Colon token.Pos
620 Value *Ident
621 In token.Pos
622 Source Expr
623
624 comments
625 clause
626 }
627
628
629 type IfClause struct {
630 If token.Pos
631 Condition Expr
632
633 comments
634 clause
635 }
636
637
638 type LetClause struct {
639 Let token.Pos
640 Ident *Ident
641 Equal token.Pos
642 Expr Expr
643
644 comments
645 clause
646 decl
647 }
648
649
650 type ParenExpr struct {
651 Lparen token.Pos
652 X Expr
653 Rparen token.Pos
654
655 comments
656 expr
657 label
658 }
659
660
661 type SelectorExpr struct {
662 X Expr
663 Sel Label
664
665 comments
666 expr
667 }
668
669
670
671 func NewSel(x Expr, sel ...string) Expr {
672 for _, s := range sel {
673 x = &SelectorExpr{X: x, Sel: NewIdent(s)}
674 }
675 return x
676 }
677
678
679 type IndexExpr struct {
680 X Expr
681 Lbrack token.Pos
682 Index Expr
683 Rbrack token.Pos
684
685 comments
686 expr
687 }
688
689
690 type SliceExpr struct {
691 X Expr
692 Lbrack token.Pos
693 Low Expr
694 High Expr
695 Rbrack token.Pos
696
697 comments
698 expr
699 }
700
701
702 type CallExpr struct {
703 Fun Expr
704 Lparen token.Pos
705 Args []Expr
706 Rparen token.Pos
707
708 comments
709 expr
710 }
711
712
713
714 func NewCall(fun Expr, args ...Expr) *CallExpr {
715 return &CallExpr{Fun: fun, Args: args}
716 }
717
718
719 type UnaryExpr struct {
720 OpPos token.Pos
721 Op token.Token
722 X Expr
723
724 comments
725 expr
726 }
727
728
729 type BinaryExpr struct {
730 X Expr
731 OpPos token.Pos
732 Op token.Token
733 Y Expr
734
735 comments
736 expr
737 }
738
739
740
741
742
743 func NewBinExpr(op token.Token, operands ...Expr) Expr {
744 if len(operands) == 0 {
745 return nil
746 }
747 expr := operands[0]
748 for _, e := range operands[1:] {
749 expr = &BinaryExpr{X: expr, Op: op, Y: e}
750 }
751 return expr
752 }
753
754
755
756 func (x *BadExpr) Pos() token.Pos { return x.From }
757 func (x *BadExpr) pos() *token.Pos { return &x.From }
758 func (x *Ident) Pos() token.Pos { return x.NamePos }
759 func (x *Ident) pos() *token.Pos { return &x.NamePos }
760 func (x *BasicLit) Pos() token.Pos { return x.ValuePos }
761 func (x *BasicLit) pos() *token.Pos { return &x.ValuePos }
762 func (x *Interpolation) Pos() token.Pos { return x.Elts[0].Pos() }
763 func (x *Interpolation) pos() *token.Pos { return x.Elts[0].pos() }
764 func (x *Func) Pos() token.Pos { return x.Func }
765 func (x *Func) pos() *token.Pos { return &x.Func }
766 func (x *StructLit) Pos() token.Pos { return getPos(x) }
767 func (x *StructLit) pos() *token.Pos {
768 if x.Lbrace == token.NoPos && len(x.Elts) > 0 {
769 return x.Elts[0].pos()
770 }
771 return &x.Lbrace
772 }
773
774 func (x *ListLit) Pos() token.Pos { return x.Lbrack }
775 func (x *ListLit) pos() *token.Pos { return &x.Lbrack }
776 func (x *Ellipsis) Pos() token.Pos { return x.Ellipsis }
777 func (x *Ellipsis) pos() *token.Pos { return &x.Ellipsis }
778 func (x *LetClause) Pos() token.Pos { return x.Let }
779 func (x *LetClause) pos() *token.Pos { return &x.Let }
780 func (x *ForClause) Pos() token.Pos { return x.For }
781 func (x *ForClause) pos() *token.Pos { return &x.For }
782 func (x *IfClause) Pos() token.Pos { return x.If }
783 func (x *IfClause) pos() *token.Pos { return &x.If }
784 func (x *ParenExpr) Pos() token.Pos { return x.Lparen }
785 func (x *ParenExpr) pos() *token.Pos { return &x.Lparen }
786 func (x *SelectorExpr) Pos() token.Pos { return x.X.Pos() }
787 func (x *SelectorExpr) pos() *token.Pos { return x.X.pos() }
788 func (x *IndexExpr) Pos() token.Pos { return x.X.Pos() }
789 func (x *IndexExpr) pos() *token.Pos { return x.X.pos() }
790 func (x *SliceExpr) Pos() token.Pos { return x.X.Pos() }
791 func (x *SliceExpr) pos() *token.Pos { return x.X.pos() }
792 func (x *CallExpr) Pos() token.Pos { return x.Fun.Pos() }
793 func (x *CallExpr) pos() *token.Pos { return x.Fun.pos() }
794 func (x *UnaryExpr) Pos() token.Pos { return x.OpPos }
795 func (x *UnaryExpr) pos() *token.Pos { return &x.OpPos }
796 func (x *BinaryExpr) Pos() token.Pos { return x.X.Pos() }
797 func (x *BinaryExpr) pos() *token.Pos { return x.X.pos() }
798 func (x *BottomLit) Pos() token.Pos { return x.Bottom }
799 func (x *BottomLit) pos() *token.Pos { return &x.Bottom }
800
801 func (x *BadExpr) End() token.Pos { return x.To }
802 func (x *Ident) End() token.Pos {
803 return x.NamePos.Add(len(x.Name))
804 }
805 func (x *BasicLit) End() token.Pos { return x.ValuePos.Add(len(x.Value)) }
806
807 func (x *Interpolation) End() token.Pos { return x.Elts[len(x.Elts)-1].Pos() }
808 func (x *Func) End() token.Pos { return x.Ret.End() }
809 func (x *StructLit) End() token.Pos {
810 if x.Rbrace == token.NoPos && len(x.Elts) > 0 {
811 return x.Elts[len(x.Elts)-1].End()
812 }
813 return x.Rbrace.Add(1)
814 }
815 func (x *ListLit) End() token.Pos { return x.Rbrack.Add(1) }
816 func (x *Ellipsis) End() token.Pos {
817 if x.Type != nil {
818 return x.Type.End()
819 }
820 return x.Ellipsis.Add(3)
821 }
822 func (x *LetClause) End() token.Pos { return x.Expr.End() }
823 func (x *ForClause) End() token.Pos { return x.Source.End() }
824 func (x *IfClause) End() token.Pos { return x.Condition.End() }
825 func (x *ParenExpr) End() token.Pos { return x.Rparen.Add(1) }
826 func (x *SelectorExpr) End() token.Pos { return x.Sel.End() }
827 func (x *IndexExpr) End() token.Pos { return x.Rbrack.Add(1) }
828 func (x *SliceExpr) End() token.Pos { return x.Rbrack.Add(1) }
829 func (x *CallExpr) End() token.Pos { return x.Rparen.Add(1) }
830 func (x *UnaryExpr) End() token.Pos { return x.X.End() }
831 func (x *BinaryExpr) End() token.Pos { return x.Y.End() }
832 func (x *BottomLit) End() token.Pos { return x.Bottom.Add(1) }
833
834
835
836
837
838
839 func NewIdent(name string) *Ident {
840 return &Ident{token.NoPos, name, nil, nil, comments{}, label{}, expr{}}
841 }
842
843 func (id *Ident) String() string {
844 if id != nil {
845 return id.Name
846 }
847 return "<nil>"
848 }
849
850
851
852
853
854 type ImportSpec struct {
855 Name *Ident
856 Path *BasicLit
857 EndPos token.Pos
858
859 comments
860 }
861
862 func (*ImportSpec) specNode() {}
863
864 func NewImport(name *Ident, importPath string) *ImportSpec {
865 importPath = literal.String.Quote(importPath)
866 path := &BasicLit{Kind: token.STRING, Value: importPath}
867 return &ImportSpec{Name: name, Path: path}
868 }
869
870
871
872 func (s *ImportSpec) Pos() token.Pos { return getPos(s) }
873 func (s *ImportSpec) pos() *token.Pos {
874 if s.Name != nil {
875 return s.Name.pos()
876 }
877 return s.Path.pos()
878 }
879
880
881
882
883
884 func (s *ImportSpec) End() token.Pos {
885 if s.EndPos != token.NoPos {
886 return s.EndPos
887 }
888 return s.Path.End()
889 }
890
891
892
893
894 type BadDecl struct {
895 From, To token.Pos
896
897 comments
898 decl
899 }
900
901
902
903 type ImportDecl struct {
904 Import token.Pos
905 Lparen token.Pos
906 Specs []*ImportSpec
907 Rparen token.Pos
908
909 comments
910 decl
911 }
912
913 type Spec interface {
914 Node
915 specNode()
916 }
917
918
919
920
921
922
923 type EmbedDecl struct {
924 Expr Expr
925
926 comments
927 decl
928 }
929
930
931
932 func (d *BadDecl) Pos() token.Pos { return d.From }
933 func (d *BadDecl) pos() *token.Pos { return &d.From }
934 func (d *ImportDecl) Pos() token.Pos { return d.Import }
935 func (d *ImportDecl) pos() *token.Pos { return &d.Import }
936 func (d *EmbedDecl) Pos() token.Pos { return d.Expr.Pos() }
937 func (d *EmbedDecl) pos() *token.Pos { return d.Expr.pos() }
938
939 func (d *BadDecl) End() token.Pos { return d.To }
940 func (d *ImportDecl) End() token.Pos {
941 if d.Rparen.IsValid() {
942 return d.Rparen.Add(1)
943 }
944 if len(d.Specs) == 0 {
945 return token.NoPos
946 }
947 return d.Specs[0].End()
948 }
949 func (d *EmbedDecl) End() token.Pos { return d.Expr.End() }
950
951
952
953
954
955
956
957
958
959 type File struct {
960 Filename string
961 Decls []Decl
962
963 Imports []*ImportSpec
964 Unresolved []*Ident
965
966 comments
967 }
968
969
970 func (f *File) Preamble() []Decl {
971 p := 0
972 outer:
973 for i, d := range f.Decls {
974 switch d.(type) {
975 default:
976 break outer
977
978 case *Package:
979 p = i + 1
980 case *CommentGroup:
981 case *Attribute:
982 case *ImportDecl:
983 p = i + 1
984 }
985 }
986 return f.Decls[:p]
987 }
988
989 func (f *File) VisitImports(fn func(d *ImportDecl)) {
990 for _, d := range f.Decls {
991 switch x := d.(type) {
992 case *CommentGroup:
993 case *Package:
994 case *Attribute:
995 case *ImportDecl:
996 fn(x)
997 default:
998 return
999 }
1000 }
1001 }
1002
1003
1004
1005 func (f *File) PackageName() string {
1006 for _, d := range f.Decls {
1007 switch x := d.(type) {
1008 case *Package:
1009 return x.Name.Name
1010 case *CommentGroup, *Attribute:
1011 default:
1012 return ""
1013 }
1014 }
1015 return ""
1016 }
1017
1018 func (f *File) Pos() token.Pos {
1019 if len(f.Decls) > 0 {
1020 return f.Decls[0].Pos()
1021 }
1022 if f.Filename != "" {
1023
1024 return token.NewFile(f.Filename, -1, 1).Pos(0, 0)
1025 }
1026 return token.NoPos
1027 }
1028
1029 func (f *File) pos() *token.Pos {
1030 if len(f.Decls) > 0 {
1031 return f.Decls[0].pos()
1032 }
1033 if f.Filename != "" {
1034 return nil
1035 }
1036 return nil
1037 }
1038
1039 func (f *File) End() token.Pos {
1040 if n := len(f.Decls); n > 0 {
1041 return f.Decls[n-1].End()
1042 }
1043 return token.NoPos
1044 }
1045
1046
1047 type Package struct {
1048 PackagePos token.Pos
1049 Name *Ident
1050
1051 comments
1052 decl
1053 }
1054
1055 func (p *Package) Pos() token.Pos { return getPos(p) }
1056 func (p *Package) pos() *token.Pos {
1057 if p.PackagePos != token.NoPos {
1058 return &p.PackagePos
1059 }
1060 if p.Name != nil {
1061 return p.Name.pos()
1062 }
1063 return nil
1064 }
1065
1066 func (p *Package) End() token.Pos {
1067 if p.Name != nil {
1068 return p.Name.End()
1069 }
1070 return token.NoPos
1071 }
1072
View as plain text