blob: bf9ca8d794eec8c77e9ae07c24130935b40b4cf2 [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
Marcel van Lohuizend96ad3d2018-12-10 15:30:20 +0100146 case *ast.Ident:
147 return v.Name
148
Marcel van Lohuizend96ad3d2018-12-10 15:30:20 +0100149 case *ast.TemplateLabel:
150 out := "<"
151 out += debugStr(v.Ident)
152 out += ">"
153 return out
154
155 case *ast.SelectorExpr:
156 return debugStr(v.X) + "." + debugStr(v.Sel)
157
158 case *ast.CallExpr:
159 out := debugStr(v.Fun)
160 out += "("
161 out += debugStr(v.Args)
162 out += ")"
163 return out
164
165 case *ast.Ellipsis:
166 return debugStr(v.Elt) + "..."
167
168 case *ast.ParenExpr:
169 out := "("
170 out += debugStr(v.X)
171 out += ")"
172 return out
173
174 case *ast.UnaryExpr:
175 return v.Op.String() + debugStr(v.X)
176
177 case *ast.BinaryExpr:
178 out := debugStr(v.X)
179 op := v.Op.String()
180 if 'a' <= op[0] && op[0] <= 'z' {
181 op = fmt.Sprintf(" %s ", op)
182 }
183 out += op
184 out += debugStr(v.Y)
185 return out
186
187 case []*ast.CommentGroup:
188 var a []string
189 for _, c := range v {
190 a = append(a, debugStr(c))
191 }
192 return strings.Join(a, "\n")
193
194 case *ast.CommentGroup:
195 str := "["
196 if v.Doc {
197 str += "d"
198 }
199 if v.Line {
200 str += "l"
201 }
202 str += strconv.Itoa(int(v.Position))
203 var a = []string{}
204 for _, c := range v.List {
205 a = append(a, c.Text)
206 }
207 return str + strings.Join(a, " ") + "] "
208
209 case *ast.IndexExpr:
210 out := debugStr(v.X)
211 out += "["
212 out += debugStr(v.Index)
213 out += "]"
214 return out
215
216 case *ast.SliceExpr:
217 out := debugStr(v.X)
218 out += "["
219 out += debugStr(v.Low)
220 out += ":"
221 out += debugStr(v.High)
222 out += "]"
223 return out
224
225 case *ast.ImportSpec:
226 out := ""
227 if v.Name != nil {
228 out += debugStr(v.Name)
229 out += " "
230 }
231 out += debugStr(v.Path)
232 return out
233
234 case []ast.Decl:
235 if len(v) == 0 {
236 return ""
237 }
238 out := ""
239 for _, d := range v {
240 out += debugStr(d)
241 out += sep
242 }
243 return out[:len(out)-len(sep)]
244
245 case []ast.Clause:
246 if len(v) == 0 {
247 return ""
248 }
249 out := ""
250 for _, c := range v {
251 out += debugStr(c)
252 out += " "
253 }
254 return out
255
256 case []ast.Expr:
257 if len(v) == 0 {
258 return ""
259 }
260 out := ""
261 for _, d := range v {
262 out += debugStr(d)
263 out += sep
264 }
265 return out[:len(out)-len(sep)]
266
267 case []*ast.ImportSpec:
268 if len(v) == 0 {
269 return ""
270 }
271 out := ""
272 for _, d := range v {
273 out += debugStr(d)
274 out += sep
275 }
276 return out[:len(out)-len(sep)]
277
278 default:
279 if v == nil {
280 return ""
281 }
282 return fmt.Sprintf("<%T>", x)
283 }
284}
285
286const sep = ", "