formatter.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. package pretty
  2. import (
  3. "fmt"
  4. "io"
  5. "reflect"
  6. "strconv"
  7. "text/tabwriter"
  8. "github.com/kr/text"
  9. "github.com/rogpeppe/go-internal/fmtsort"
  10. )
  11. type formatter struct {
  12. v reflect.Value
  13. force bool
  14. quote bool
  15. }
  16. // Formatter makes a wrapper, f, that will format x as go source with line
  17. // breaks and tabs. Object f responds to the "%v" formatting verb when both the
  18. // "#" and " " (space) flags are set, for example:
  19. //
  20. // fmt.Sprintf("%# v", Formatter(x))
  21. //
  22. // If one of these two flags is not set, or any other verb is used, f will
  23. // format x according to the usual rules of package fmt.
  24. // In particular, if x satisfies fmt.Formatter, then x.Format will be called.
  25. func Formatter(x interface{}) (f fmt.Formatter) {
  26. return formatter{v: reflect.ValueOf(x), quote: true}
  27. }
  28. func (fo formatter) String() string {
  29. return fmt.Sprint(fo.v.Interface()) // unwrap it
  30. }
  31. func (fo formatter) passThrough(f fmt.State, c rune) {
  32. s := "%"
  33. for i := 0; i < 128; i++ {
  34. if f.Flag(i) {
  35. s += string(rune(i))
  36. }
  37. }
  38. if w, ok := f.Width(); ok {
  39. s += fmt.Sprintf("%d", w)
  40. }
  41. if p, ok := f.Precision(); ok {
  42. s += fmt.Sprintf(".%d", p)
  43. }
  44. s += string(c)
  45. fmt.Fprintf(f, s, fo.v.Interface())
  46. }
  47. func (fo formatter) Format(f fmt.State, c rune) {
  48. if fo.force || c == 'v' && f.Flag('#') && f.Flag(' ') {
  49. w := tabwriter.NewWriter(f, 4, 4, 1, ' ', 0)
  50. p := &printer{tw: w, Writer: w, visited: make(map[visit]int)}
  51. p.printValue(fo.v, true, fo.quote)
  52. w.Flush()
  53. return
  54. }
  55. fo.passThrough(f, c)
  56. }
  57. type printer struct {
  58. io.Writer
  59. tw *tabwriter.Writer
  60. visited map[visit]int
  61. depth int
  62. }
  63. func (p *printer) indent() *printer {
  64. q := *p
  65. q.tw = tabwriter.NewWriter(p.Writer, 4, 4, 1, ' ', 0)
  66. q.Writer = text.NewIndentWriter(q.tw, []byte{'\t'})
  67. return &q
  68. }
  69. func (p *printer) printInline(v reflect.Value, x interface{}, showType bool) {
  70. if showType {
  71. io.WriteString(p, v.Type().String())
  72. fmt.Fprintf(p, "(%#v)", x)
  73. } else {
  74. fmt.Fprintf(p, "%#v", x)
  75. }
  76. }
  77. // printValue must keep track of already-printed pointer values to avoid
  78. // infinite recursion.
  79. type visit struct {
  80. v uintptr
  81. typ reflect.Type
  82. }
  83. func (p *printer) printValue(v reflect.Value, showType, quote bool) {
  84. if p.depth > 10 {
  85. io.WriteString(p, "!%v(DEPTH EXCEEDED)")
  86. return
  87. }
  88. if v.IsValid() && v.CanInterface() {
  89. i := v.Interface()
  90. if goStringer, ok := i.(fmt.GoStringer); ok {
  91. io.WriteString(p, goStringer.GoString())
  92. return
  93. }
  94. }
  95. switch v.Kind() {
  96. case reflect.Bool:
  97. p.printInline(v, v.Bool(), showType)
  98. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  99. p.printInline(v, v.Int(), showType)
  100. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  101. p.printInline(v, v.Uint(), showType)
  102. case reflect.Float32, reflect.Float64:
  103. p.printInline(v, v.Float(), showType)
  104. case reflect.Complex64, reflect.Complex128:
  105. fmt.Fprintf(p, "%#v", v.Complex())
  106. case reflect.String:
  107. p.fmtString(v.String(), quote)
  108. case reflect.Map:
  109. t := v.Type()
  110. if showType {
  111. io.WriteString(p, t.String())
  112. }
  113. writeByte(p, '{')
  114. if nonzero(v) {
  115. expand := !canInline(v.Type())
  116. pp := p
  117. if expand {
  118. writeByte(p, '\n')
  119. pp = p.indent()
  120. }
  121. sm := fmtsort.Sort(v)
  122. for i := 0; i < v.Len(); i++ {
  123. k := sm.Key[i]
  124. mv := sm.Value[i]
  125. pp.printValue(k, false, true)
  126. writeByte(pp, ':')
  127. if expand {
  128. writeByte(pp, '\t')
  129. }
  130. showTypeInStruct := t.Elem().Kind() == reflect.Interface
  131. pp.printValue(mv, showTypeInStruct, true)
  132. if expand {
  133. io.WriteString(pp, ",\n")
  134. } else if i < v.Len()-1 {
  135. io.WriteString(pp, ", ")
  136. }
  137. }
  138. if expand {
  139. pp.tw.Flush()
  140. }
  141. }
  142. writeByte(p, '}')
  143. case reflect.Struct:
  144. t := v.Type()
  145. if v.CanAddr() {
  146. addr := v.UnsafeAddr()
  147. vis := visit{addr, t}
  148. if vd, ok := p.visited[vis]; ok && vd < p.depth {
  149. p.fmtString(t.String()+"{(CYCLIC REFERENCE)}", false)
  150. break // don't print v again
  151. }
  152. p.visited[vis] = p.depth
  153. }
  154. if showType {
  155. io.WriteString(p, t.String())
  156. }
  157. writeByte(p, '{')
  158. if nonzero(v) {
  159. expand := !canInline(v.Type())
  160. pp := p
  161. if expand {
  162. writeByte(p, '\n')
  163. pp = p.indent()
  164. }
  165. for i := 0; i < v.NumField(); i++ {
  166. showTypeInStruct := true
  167. if f := t.Field(i); f.Name != "" {
  168. io.WriteString(pp, f.Name)
  169. writeByte(pp, ':')
  170. if expand {
  171. writeByte(pp, '\t')
  172. }
  173. showTypeInStruct = labelType(f.Type)
  174. }
  175. pp.printValue(getField(v, i), showTypeInStruct, true)
  176. if expand {
  177. io.WriteString(pp, ",\n")
  178. } else if i < v.NumField()-1 {
  179. io.WriteString(pp, ", ")
  180. }
  181. }
  182. if expand {
  183. pp.tw.Flush()
  184. }
  185. }
  186. writeByte(p, '}')
  187. case reflect.Interface:
  188. switch e := v.Elem(); {
  189. case e.Kind() == reflect.Invalid:
  190. io.WriteString(p, "nil")
  191. case e.IsValid():
  192. pp := *p
  193. pp.depth++
  194. pp.printValue(e, showType, true)
  195. default:
  196. io.WriteString(p, v.Type().String())
  197. io.WriteString(p, "(nil)")
  198. }
  199. case reflect.Array, reflect.Slice:
  200. t := v.Type()
  201. if showType {
  202. io.WriteString(p, t.String())
  203. }
  204. if v.Kind() == reflect.Slice && v.IsNil() && showType {
  205. io.WriteString(p, "(nil)")
  206. break
  207. }
  208. if v.Kind() == reflect.Slice && v.IsNil() {
  209. io.WriteString(p, "nil")
  210. break
  211. }
  212. writeByte(p, '{')
  213. expand := !canInline(v.Type())
  214. pp := p
  215. if expand {
  216. writeByte(p, '\n')
  217. pp = p.indent()
  218. }
  219. for i := 0; i < v.Len(); i++ {
  220. showTypeInSlice := t.Elem().Kind() == reflect.Interface
  221. pp.printValue(v.Index(i), showTypeInSlice, true)
  222. if expand {
  223. io.WriteString(pp, ",\n")
  224. } else if i < v.Len()-1 {
  225. io.WriteString(pp, ", ")
  226. }
  227. }
  228. if expand {
  229. pp.tw.Flush()
  230. }
  231. writeByte(p, '}')
  232. case reflect.Ptr:
  233. e := v.Elem()
  234. if !e.IsValid() {
  235. writeByte(p, '(')
  236. io.WriteString(p, v.Type().String())
  237. io.WriteString(p, ")(nil)")
  238. } else {
  239. pp := *p
  240. pp.depth++
  241. writeByte(pp, '&')
  242. pp.printValue(e, true, true)
  243. }
  244. case reflect.Chan:
  245. x := v.Pointer()
  246. if showType {
  247. writeByte(p, '(')
  248. io.WriteString(p, v.Type().String())
  249. fmt.Fprintf(p, ")(%#v)", x)
  250. } else {
  251. fmt.Fprintf(p, "%#v", x)
  252. }
  253. case reflect.Func:
  254. io.WriteString(p, v.Type().String())
  255. io.WriteString(p, " {...}")
  256. case reflect.UnsafePointer:
  257. p.printInline(v, v.Pointer(), showType)
  258. case reflect.Invalid:
  259. io.WriteString(p, "nil")
  260. }
  261. }
  262. func canInline(t reflect.Type) bool {
  263. switch t.Kind() {
  264. case reflect.Map:
  265. return !canExpand(t.Elem())
  266. case reflect.Struct:
  267. for i := 0; i < t.NumField(); i++ {
  268. if canExpand(t.Field(i).Type) {
  269. return false
  270. }
  271. }
  272. return true
  273. case reflect.Interface:
  274. return false
  275. case reflect.Array, reflect.Slice:
  276. return !canExpand(t.Elem())
  277. case reflect.Ptr:
  278. return false
  279. case reflect.Chan, reflect.Func, reflect.UnsafePointer:
  280. return false
  281. }
  282. return true
  283. }
  284. func canExpand(t reflect.Type) bool {
  285. switch t.Kind() {
  286. case reflect.Map, reflect.Struct,
  287. reflect.Interface, reflect.Array, reflect.Slice,
  288. reflect.Ptr:
  289. return true
  290. }
  291. return false
  292. }
  293. func labelType(t reflect.Type) bool {
  294. switch t.Kind() {
  295. case reflect.Interface, reflect.Struct:
  296. return true
  297. }
  298. return false
  299. }
  300. func (p *printer) fmtString(s string, quote bool) {
  301. if quote {
  302. s = strconv.Quote(s)
  303. }
  304. io.WriteString(p, s)
  305. }
  306. func writeByte(w io.Writer, b byte) {
  307. w.Write([]byte{b})
  308. }
  309. func getField(v reflect.Value, i int) reflect.Value {
  310. val := v.Field(i)
  311. if val.Kind() == reflect.Interface && !val.IsNil() {
  312. val = val.Elem()
  313. }
  314. return val
  315. }