this repo has no description
at master 382 lines 6.4 kB view raw
1// Copyright 2020 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 15// Package debug prints a given ADT node. 16// 17// Note that the result is not valid CUE, but instead prints the internals 18// of an ADT node in human-readable form. It uses a simple indentation algorithm 19// for improved readability and diffing. 20package debug 21 22import ( 23 "fmt" 24 "strconv" 25 26 "cuelang.org/go/cue/literal" 27 "cuelang.org/go/internal/core/adt" 28) 29 30func (w *printer) compactNode(n adt.Node) { 31 switch x := n.(type) { 32 case *adt.Vertex: 33 if x.BaseValue == nil || (w.cfg.Raw && !x.IsData()) { 34 i := 0 35 for c := range x.LeafConjuncts() { 36 if i > 0 { 37 w.string(" & ") 38 } 39 i++ 40 w.node(c.Elem()) 41 } 42 return 43 } 44 45 switch v := x.BaseValue.(type) { 46 case *adt.StructMarker: 47 if !w.pushVertex(x) { 48 return 49 } 50 defer w.popVertex() 51 52 w.string("{") 53 for i, a := range x.Arcs { 54 if i > 0 { 55 w.string(",") 56 } 57 if a.Label.IsLet() { 58 w.string("let ") 59 w.label(a.Label) 60 if a.MultiLet { 61 w.string("m") 62 } 63 w.string("=") 64 if c := a.ConjunctAt(0); a.MultiLet { 65 w.node(c.Expr()) 66 continue 67 } 68 w.node(a) 69 } else { 70 w.label(a.Label) 71 w.string(a.ArcType.Suffix()) 72 w.string(":") 73 w.node(a) 74 } 75 } 76 w.string("}") 77 78 case *adt.ListMarker: 79 if !w.pushVertex(x) { 80 return 81 } 82 defer w.popVertex() 83 84 w.string("[") 85 for i, a := range x.Arcs { 86 if i > 0 { 87 w.string(",") 88 } 89 w.node(a) 90 } 91 w.string("]") 92 93 case *adt.Vertex: 94 // Disjunction, structure shared, etc. 95 96 if v, ok := w.printShared(x); !ok { 97 w.node(v) 98 w.popVertex() 99 } 100 101 case adt.Value: 102 w.node(v) 103 } 104 105 case *adt.StructMarker: 106 w.string("struct") 107 108 case *adt.ListMarker: 109 w.string("list") 110 111 case *adt.StructLit: 112 w.string("{") 113 for i, d := range x.Decls { 114 if i > 0 { 115 w.string(",") 116 } 117 w.node(d) 118 } 119 w.string("}") 120 121 case *adt.ListLit: 122 w.string("[") 123 for i, d := range x.Elems { 124 if i > 0 { 125 w.string(",") 126 } 127 w.node(d) 128 } 129 w.string("]") 130 131 case *adt.Field: 132 w.label(x.Label) 133 w.string(x.ArcType.Suffix()) 134 w.string(":") 135 w.node(x.Value) 136 137 case *adt.LetField: 138 w.string("let ") 139 w.label(x.Label) 140 if x.IsMulti { 141 w.string("m") 142 } 143 w.string("=") 144 w.node(x.Value) 145 146 case *adt.BulkOptionalField: 147 w.string("[") 148 w.node(x.Filter) 149 w.string("]:") 150 w.node(x.Value) 151 152 case *adt.DynamicField: 153 w.node(x.Key) 154 w.string(x.ArcType.Suffix()) 155 w.string(":") 156 w.node(x.Value) 157 158 case *adt.Ellipsis: 159 w.string("...") 160 if x.Value != nil { 161 w.node(x.Value) 162 } 163 164 case *adt.Bottom: 165 w.string(`_|_`) 166 if x.Err != nil { 167 w.string("(") 168 w.shortError(x.Err, false) 169 w.string(")") 170 } 171 172 case *adt.Null: 173 w.string("null") 174 175 case *adt.Bool: 176 w.dst = strconv.AppendBool(w.dst, x.B) 177 178 case *adt.Num: 179 w.string(x.X.String()) 180 181 case *adt.String: 182 w.dst = literal.String.Append(w.dst, x.Str) 183 184 case *adt.Bytes: 185 w.dst = literal.Bytes.Append(w.dst, string(x.B)) 186 187 case *adt.Top: 188 w.string("_") 189 190 case *adt.BasicType: 191 w.string(x.K.String()) 192 193 case *adt.BoundExpr: 194 w.string(x.Op.String()) 195 w.node(x.Expr) 196 197 case *adt.BoundValue: 198 w.string(x.Op.String()) 199 w.node(x.Value) 200 201 case *adt.NodeLink: 202 w.string(openTuple) 203 for i, f := range x.Node.Path() { 204 if i > 0 { 205 w.string(".") 206 } 207 w.label(f) 208 } 209 w.string(closeTuple) 210 211 case *adt.FieldReference: 212 w.label(x.Label) 213 214 case *adt.ValueReference: 215 w.label(x.Label) 216 217 case *adt.LabelReference: 218 if x.Src == nil { 219 w.string("LABEL") 220 } else { 221 w.string(x.Src.Name) 222 } 223 224 case *adt.DynamicReference: 225 w.node(x.Label) 226 227 case *adt.ImportReference: 228 w.label(x.ImportPath) 229 230 case *adt.LetReference: 231 w.ident(x.Label) 232 233 case *adt.SelectorExpr: 234 w.node(x.X) 235 w.string(".") 236 w.label(x.Sel) 237 238 case *adt.IndexExpr: 239 w.node(x.X) 240 w.string("[") 241 w.node(x.Index) 242 w.string("]") 243 244 case *adt.SliceExpr: 245 w.node(x.X) 246 w.string("[") 247 if x.Lo != nil { 248 w.node(x.Lo) 249 } 250 w.string(":") 251 if x.Hi != nil { 252 w.node(x.Hi) 253 } 254 if x.Stride != nil { 255 w.string(":") 256 w.node(x.Stride) 257 } 258 w.string("]") 259 260 case *adt.Interpolation: 261 w.interpolation(x) 262 263 case *adt.UnaryExpr: 264 w.string(x.Op.String()) 265 w.node(x.X) 266 267 case *adt.BinaryExpr: 268 w.string("(") 269 w.node(x.X) 270 w.string(" ") 271 w.string(x.Op.String()) 272 w.string(" ") 273 w.node(x.Y) 274 w.string(")") 275 276 case *adt.OpenExpr: 277 w.node(x.X) 278 w.string("...") 279 280 case *adt.CallExpr: 281 w.node(x.Fun) 282 w.string("(") 283 for i, a := range x.Args { 284 if i > 0 { 285 w.string(", ") 286 } 287 w.arg(a) 288 } 289 w.string(")") 290 291 case *adt.Builtin: 292 if x.Package != 0 { 293 w.label(x.Package) 294 w.string(".") 295 } 296 w.string(x.Name) 297 298 case *adt.BuiltinValidator: 299 w.node(x.Builtin) 300 w.string("(") 301 for i, a := range x.Args { 302 if i > 0 { 303 w.string(", ") 304 } 305 w.arg(a) 306 } 307 w.string(")") 308 309 case *adt.DisjunctionExpr: 310 w.string("(") 311 for i, a := range x.Values { 312 if i > 0 { 313 w.string("|") 314 } 315 // Disjunct 316 if a.Default { 317 w.string("*") 318 } 319 w.node(a.Val) 320 } 321 w.string(")") 322 323 case *adt.Conjunction: 324 for i, c := range x.Values { 325 if i > 0 { 326 w.string(" & ") 327 } 328 w.node(c) 329 } 330 331 case *adt.ConjunctGroup: 332 for i, c := range *x { 333 if i > 0 { 334 w.string(" & ") 335 } 336 w.node(c.Expr()) 337 } 338 339 case *adt.Disjunction: 340 for i, c := range x.Values { 341 if i > 0 { 342 w.string(" | ") 343 } 344 if i < x.NumDefaults { 345 w.string("*") 346 } 347 w.node(c) 348 } 349 350 case *adt.Comprehension: 351 for _, c := range x.Clauses { 352 w.node(c) 353 } 354 w.node(adt.ToExpr(x.Value)) 355 356 case *adt.ForClause: 357 w.string("for ") 358 w.ident(x.Key) 359 w.string(", ") 360 w.ident(x.Value) 361 w.string(" in ") 362 w.node(x.Src) 363 w.string(" ") 364 365 case *adt.IfClause: 366 w.string("if ") 367 w.node(x.Condition) 368 w.string(" ") 369 370 case *adt.LetClause: 371 w.string("let ") 372 w.ident(x.Label) 373 w.string(" = ") 374 w.node(x.Expr) 375 w.string(" ") 376 377 case *adt.ValueClause: 378 379 default: 380 panic(fmt.Sprintf("unknown type %T", x)) 381 } 382}