in starlark/value.go [1131:1220]
func writeValue(out *strings.Builder, x Value, path []Value) {
switch x := x.(type) {
case nil:
out.WriteString("<nil>") // indicates a bug
// These four cases are duplicates of T.String(), for efficiency.
case NoneType:
out.WriteString("None")
case Int:
out.WriteString(x.String())
case Bool:
if x {
out.WriteString("True")
} else {
out.WriteString("False")
}
case String:
out.WriteString(syntax.Quote(string(x), false))
case *List:
out.WriteByte('[')
if pathContains(path, x) {
out.WriteString("...") // list contains itself
} else {
for i, elem := range x.elems {
if i > 0 {
out.WriteString(", ")
}
writeValue(out, elem, append(path, x))
}
}
out.WriteByte(']')
case Tuple:
out.WriteByte('(')
for i, elem := range x {
if i > 0 {
out.WriteString(", ")
}
writeValue(out, elem, path)
}
if len(x) == 1 {
out.WriteByte(',')
}
out.WriteByte(')')
case *Function:
fmt.Fprintf(out, "<function %s>", x.Name())
case *Builtin:
if x.recv != nil {
fmt.Fprintf(out, "<built-in method %s of %s value>", x.Name(), x.recv.Type())
} else {
fmt.Fprintf(out, "<built-in function %s>", x.Name())
}
case *Dict:
out.WriteByte('{')
if pathContains(path, x) {
out.WriteString("...") // dict contains itself
} else {
sep := ""
for e := x.ht.head; e != nil; e = e.next {
k, v := e.key, e.value
out.WriteString(sep)
writeValue(out, k, path)
out.WriteString(": ")
writeValue(out, v, append(path, x)) // cycle check
sep = ", "
}
}
out.WriteByte('}')
case *Set:
out.WriteString("set([")
for i, elem := range x.elems() {
if i > 0 {
out.WriteString(", ")
}
writeValue(out, elem, path)
}
out.WriteString("])")
default:
out.WriteString(x.String())
}
}