blob: b02efcc95cb0a727ac0e54d5150aa6d76d7e5f8f [file] [log] [blame]
Marcel van Lohuizend96ad3d2018-12-10 15:30:20 +01001// Copyright 2018 The CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package parser
16
17import (
18 "fmt"
19 "strconv"
20 "strings"
21
22 "cuelang.org/go/cue/ast"
23 "cuelang.org/go/cue/token"
24 "cuelang.org/go/internal"
25)
26
27func init() {
28 internal.DebugStr = debugStr
29}
30
31func debugStr(x interface{}) (out string) {
32 if n, ok := x.(ast.Node); ok {
33 comments := ""
34 for _, g := range n.Comments() {
35 comments += debugStr(g)
36 }
37 if comments != "" {
38 defer func() { out = "<" + comments + out + ">" }()
39 }
40 }
41 switch v := x.(type) {
42 case *ast.File:
43 out := ""
44 if v.Name != nil {
45 out += "package "
46 out += debugStr(v.Name)
47 out += ", "
48 }
49 out += debugStr(v.Decls)
50 return out
51
52 case *ast.Alias:
53 out := debugStr(v.Ident)
54 out += " = "
55 out += debugStr(v.Expr)
56 return out
57
58 case *ast.BottomLit:
59 return "_|_"
60
61 case *ast.BasicLit:
62 return v.Value
63
64 case *ast.Interpolation:
65 for _, e := range v.Elts {
66 out += debugStr(e)
67 }
68 return out
69
70 case *ast.EmitDecl:
71 // out := "<"
72 out += debugStr(v.Expr)
73 // out += ">"
74 return out
75
76 case *ast.ImportDecl:
77 out := "import "
78 if v.Lparen != token.NoPos {
79 out += "( "
80 out += debugStr(v.Specs)
81 out += " )"
82 } else {
83 out += debugStr(v.Specs)
84 }
85 return out
86
87 case *ast.ComprehensionDecl:
88 out := debugStr(v.Field)
89 out += " "
90 out += debugStr(v.Clauses)
91 return out
92
93 case *ast.StructLit:
94 out := "{"
95 out += debugStr(v.Elts)
96 out += "}"
97 return out
98
99 case *ast.ListLit:
100 out := "["
101 out += debugStr(v.Elts)
102 if v.Ellipsis != token.NoPos || v.Type != nil {
103 if out != "[" {
104 out += ", "
105 }
106 out += "..."
107 if v.Type != nil {
108 out += debugStr(v.Type)
109 }
110 }
111 out += "]"
112 return out
113
114 case *ast.ListComprehension:
115 out := "["
116 out += debugStr(v.Expr)
117 out += " "
118 out += debugStr(v.Clauses)
119 out += "]"
120 return out
121
122 case *ast.ForClause:
123 out := "for "
124 if v.Key != nil {
125 out += debugStr(v.Key)
126 out += ": "
127 }
128 out += debugStr(v.Value)
129 out += " in "
130 out += debugStr(v.Source)
131 return out
132
133 case *ast.IfClause:
134 out := "if "
135 out += debugStr(v.Condition)
136 return out
137
138 case *ast.Field:
139 out := debugStr(v.Label)
140 if v.Value != nil {
141 out += ": "
142 out += debugStr(v.Value)
143 }
144 return out
145
146 case *ast.LambdaExpr:
147 out := "("
148 for _, m := range v.Params {
149 out += debugStr(m)
150 out += ","
151 }
152 out += ") -> "
153 out += debugStr(v.Expr)
154 return out
155
156 case *ast.Ident:
157 return v.Name
158
Marcel van Lohuizend96ad3d2018-12-10 15:30:20 +0100159 case *ast.TemplateLabel:
160 out := "<"
161 out += debugStr(v.Ident)
162 out += ">"
163 return out
164
165 case *ast.SelectorExpr:
166 return debugStr(v.X) + "." + debugStr(v.Sel)
167
168 case *ast.CallExpr:
169 out := debugStr(v.Fun)
170 out += "("
171 out += debugStr(v.Args)
172 out += ")"
173 return out
174
175 case *ast.Ellipsis:
176 return debugStr(v.Elt) + "..."
177
178 case *ast.ParenExpr:
179 out := "("
180 out += debugStr(v.X)
181 out += ")"
182 return out
183
184 case *ast.UnaryExpr:
185 return v.Op.String() + debugStr(v.X)
186
187 case *ast.BinaryExpr:
188 out := debugStr(v.X)
189 op := v.Op.String()
190 if 'a' <= op[0] && op[0] <= 'z' {
191 op = fmt.Sprintf(" %s ", op)
192 }
193 out += op
194 out += debugStr(v.Y)
195 return out
196
197 case []*ast.CommentGroup:
198 var a []string
199 for _, c := range v {
200 a = append(a, debugStr(c))
201 }
202 return strings.Join(a, "\n")
203
204 case *ast.CommentGroup:
205 str := "["
206 if v.Doc {
207 str += "d"
208 }
209 if v.Line {
210 str += "l"
211 }
212 str += strconv.Itoa(int(v.Position))
213 var a = []string{}
214 for _, c := range v.List {
215 a = append(a, c.Text)
216 }
217 return str + strings.Join(a, " ") + "] "
218
219 case *ast.IndexExpr:
220 out := debugStr(v.X)
221 out += "["
222 out += debugStr(v.Index)
223 out += "]"
224 return out
225
226 case *ast.SliceExpr:
227 out := debugStr(v.X)
228 out += "["
229 out += debugStr(v.Low)
230 out += ":"
231 out += debugStr(v.High)
232 out += "]"
233 return out
234
235 case *ast.ImportSpec:
236 out := ""
237 if v.Name != nil {
238 out += debugStr(v.Name)
239 out += " "
240 }
241 out += debugStr(v.Path)
242 return out
243
244 case []ast.Decl:
245 if len(v) == 0 {
246 return ""
247 }
248 out := ""
249 for _, d := range v {
250 out += debugStr(d)
251 out += sep
252 }
253 return out[:len(out)-len(sep)]
254
255 case []ast.Clause:
256 if len(v) == 0 {
257 return ""
258 }
259 out := ""
260 for _, c := range v {
261 out += debugStr(c)
262 out += " "
263 }
264 return out
265
266 case []ast.Expr:
267 if len(v) == 0 {
268 return ""
269 }
270 out := ""
271 for _, d := range v {
272 out += debugStr(d)
273 out += sep
274 }
275 return out[:len(out)-len(sep)]
276
277 case []*ast.ImportSpec:
278 if len(v) == 0 {
279 return ""
280 }
281 out := ""
282 for _, d := range v {
283 out += debugStr(d)
284 out += sep
285 }
286 return out[:len(out)-len(sep)]
287
288 default:
289 if v == nil {
290 return ""
291 }
292 return fmt.Sprintf("<%T>", x)
293 }
294}
295
296const sep = ", "