...

Source file src/cuelang.org/go/internal/core/debug/compact.go

Documentation: cuelang.org/go/internal/core/debug

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

View as plain text