Source file src/go/types/exprstring.go
1
2
3
4
5
6
7 package types
8
9 import (
10 "bytes"
11 "go/ast"
12 )
13
14
15
16
17 func ExprString(x ast.Expr) string {
18 var buf bytes.Buffer
19 WriteExpr(&buf, x)
20 return buf.String()
21 }
22
23
24
25
26 func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
27
28
29
30
31
32 switch x := x.(type) {
33 default:
34 buf.WriteString("(bad expr)")
35
36 case *ast.Ident:
37 buf.WriteString(x.Name)
38
39 case *ast.Ellipsis:
40 buf.WriteString("...")
41 if x.Elt != nil {
42 WriteExpr(buf, x.Elt)
43 }
44
45 case *ast.BasicLit:
46 buf.WriteString(x.Value)
47
48 case *ast.FuncLit:
49 buf.WriteByte('(')
50 WriteExpr(buf, x.Type)
51 buf.WriteString(" literal)")
52
53 case *ast.CompositeLit:
54 buf.WriteByte('(')
55 WriteExpr(buf, x.Type)
56 buf.WriteString(" literal)")
57
58 case *ast.ParenExpr:
59 buf.WriteByte('(')
60 WriteExpr(buf, x.X)
61 buf.WriteByte(')')
62
63 case *ast.SelectorExpr:
64 WriteExpr(buf, x.X)
65 buf.WriteByte('.')
66 buf.WriteString(x.Sel.Name)
67
68 case *ast.IndexExpr:
69 WriteExpr(buf, x.X)
70 buf.WriteByte('[')
71 WriteExpr(buf, x.Index)
72 buf.WriteByte(']')
73
74 case *ast.SliceExpr:
75 WriteExpr(buf, x.X)
76 buf.WriteByte('[')
77 if x.Low != nil {
78 WriteExpr(buf, x.Low)
79 }
80 buf.WriteByte(':')
81 if x.High != nil {
82 WriteExpr(buf, x.High)
83 }
84 if x.Slice3 {
85 buf.WriteByte(':')
86 if x.Max != nil {
87 WriteExpr(buf, x.Max)
88 }
89 }
90 buf.WriteByte(']')
91
92 case *ast.TypeAssertExpr:
93 WriteExpr(buf, x.X)
94 buf.WriteString(".(")
95 WriteExpr(buf, x.Type)
96 buf.WriteByte(')')
97
98 case *ast.CallExpr:
99 WriteExpr(buf, x.Fun)
100 buf.WriteByte('(')
101 for i, arg := range x.Args {
102 if i > 0 {
103 buf.WriteString(", ")
104 }
105 WriteExpr(buf, arg)
106 }
107 if x.Ellipsis.IsValid() {
108 buf.WriteString("...")
109 }
110 buf.WriteByte(')')
111
112 case *ast.StarExpr:
113 buf.WriteByte('*')
114 WriteExpr(buf, x.X)
115
116 case *ast.UnaryExpr:
117 buf.WriteString(x.Op.String())
118 WriteExpr(buf, x.X)
119
120 case *ast.BinaryExpr:
121 WriteExpr(buf, x.X)
122 buf.WriteByte(' ')
123 buf.WriteString(x.Op.String())
124 buf.WriteByte(' ')
125 WriteExpr(buf, x.Y)
126
127 case *ast.ArrayType:
128 buf.WriteByte('[')
129 if x.Len != nil {
130 WriteExpr(buf, x.Len)
131 }
132 buf.WriteByte(']')
133 WriteExpr(buf, x.Elt)
134
135 case *ast.StructType:
136 buf.WriteString("struct{")
137 writeFieldList(buf, x.Fields, "; ", false)
138 buf.WriteByte('}')
139
140 case *ast.FuncType:
141 buf.WriteString("func")
142 writeSigExpr(buf, x)
143
144 case *ast.InterfaceType:
145 buf.WriteString("interface{")
146 writeFieldList(buf, x.Methods, "; ", true)
147 buf.WriteByte('}')
148
149 case *ast.MapType:
150 buf.WriteString("map[")
151 WriteExpr(buf, x.Key)
152 buf.WriteByte(']')
153 WriteExpr(buf, x.Value)
154
155 case *ast.ChanType:
156 var s string
157 switch x.Dir {
158 case ast.SEND:
159 s = "chan<- "
160 case ast.RECV:
161 s = "<-chan "
162 default:
163 s = "chan "
164 }
165 buf.WriteString(s)
166 WriteExpr(buf, x.Value)
167 }
168 }
169
170 func writeSigExpr(buf *bytes.Buffer, sig *ast.FuncType) {
171 buf.WriteByte('(')
172 writeFieldList(buf, sig.Params, ", ", false)
173 buf.WriteByte(')')
174
175 res := sig.Results
176 n := res.NumFields()
177 if n == 0 {
178
179 return
180 }
181
182 buf.WriteByte(' ')
183 if n == 1 && len(res.List[0].Names) == 0 {
184
185 WriteExpr(buf, res.List[0].Type)
186 return
187 }
188
189
190 buf.WriteByte('(')
191 writeFieldList(buf, res, ", ", false)
192 buf.WriteByte(')')
193 }
194
195 func writeFieldList(buf *bytes.Buffer, fields *ast.FieldList, sep string, iface bool) {
196 for i, f := range fields.List {
197 if i > 0 {
198 buf.WriteString(sep)
199 }
200
201
202 for i, name := range f.Names {
203 if i > 0 {
204 buf.WriteString(", ")
205 }
206 buf.WriteString(name.Name)
207 }
208
209
210 if sig, _ := f.Type.(*ast.FuncType); sig != nil && iface {
211 writeSigExpr(buf, sig)
212 continue
213 }
214
215
216 if len(f.Names) > 0 {
217 buf.WriteByte(' ')
218 }
219
220 WriteExpr(buf, f.Type)
221
222
223 }
224 }
225
View as plain text