| 1 | """
|
| 2 | format.py -- Pretty print an ASDL data structure.
|
| 3 | """
|
| 4 | from _devbuild.gen.hnode_asdl import hnode, hnode_e, hnode_t
|
| 5 | from _devbuild.gen.pretty_asdl import (doc, doc_e, doc_t, MeasuredDoc,
|
| 6 | List_Measured)
|
| 7 | from display import pp_hnode
|
| 8 | from display import pretty
|
| 9 | from mycpp import mylib
|
| 10 | from mycpp.mylib import log, tagswitch
|
| 11 |
|
| 12 | from typing import Any, Optional, cast
|
| 13 |
|
| 14 | _ = log
|
| 15 |
|
| 16 | if mylib.PYTHON:
|
| 17 |
|
| 18 | def PrettyPrint(obj, f=None):
|
| 19 | # type: (Any, Optional[mylib.Writer]) -> None
|
| 20 | """Print abbreviated tree in color. For unit tests."""
|
| 21 | f = f if f else mylib.Stdout()
|
| 22 | tree = obj.PrettyTree(True)
|
| 23 | HNodePrettyPrint(tree, f)
|
| 24 |
|
| 25 |
|
| 26 | def _HNodeCount(h):
|
| 27 | # type: (hnode_t) -> int
|
| 28 | """
|
| 29 | Return the size of the tree
|
| 30 | """
|
| 31 | UP_h = h
|
| 32 | with tagswitch(h) as case:
|
| 33 | if case(hnode_e.AlreadySeen):
|
| 34 | return 1
|
| 35 |
|
| 36 | elif case(hnode_e.Leaf):
|
| 37 | return 1
|
| 38 |
|
| 39 | elif case(hnode_e.Array):
|
| 40 | h = cast(hnode.Array, UP_h)
|
| 41 | n = 1 # 1 for this node
|
| 42 | for child in h.children:
|
| 43 | n += _HNodeCount(child)
|
| 44 | return n
|
| 45 |
|
| 46 | elif case(hnode_e.Record):
|
| 47 | h = cast(hnode.Record, UP_h)
|
| 48 | n = 1 # 1 for this node
|
| 49 | for field in h.fields:
|
| 50 | n += _HNodeCount(field.val)
|
| 51 |
|
| 52 | if h.unnamed_fields is not None:
|
| 53 | for child in h.unnamed_fields:
|
| 54 | n += _HNodeCount(child)
|
| 55 | return n
|
| 56 |
|
| 57 | else:
|
| 58 | raise AssertionError()
|
| 59 |
|
| 60 |
|
| 61 | def _DocCount(d):
|
| 62 | # type: (doc_t) -> int
|
| 63 | """
|
| 64 | Return the size of the tree
|
| 65 | """
|
| 66 | UP_d = d
|
| 67 | with tagswitch(d) as case:
|
| 68 | if case(doc_e.Break):
|
| 69 | return 1
|
| 70 |
|
| 71 | elif case(doc_e.Text):
|
| 72 | return 1
|
| 73 |
|
| 74 | elif case(doc_e.Indent):
|
| 75 | d = cast(doc.Indent, UP_d)
|
| 76 | return 1 + _DocCount(d.mdoc.doc)
|
| 77 |
|
| 78 | elif case(doc_e.Group):
|
| 79 | d = cast(MeasuredDoc, UP_d)
|
| 80 | return 1 + _DocCount(d.doc)
|
| 81 |
|
| 82 | elif case(doc_e.Flat):
|
| 83 | d = cast(doc.Flat, UP_d)
|
| 84 | return 1 + _DocCount(d.mdoc.doc)
|
| 85 |
|
| 86 | elif case(doc_e.IfFlat):
|
| 87 | d = cast(doc.IfFlat, UP_d)
|
| 88 | return 1 + _DocCount(d.flat_mdoc.doc) + _DocCount(
|
| 89 | d.nonflat_mdoc.doc)
|
| 90 |
|
| 91 | elif case(doc_e.Concat):
|
| 92 | d = cast(List_Measured, UP_d)
|
| 93 | n = 1 # 1 for this node
|
| 94 | for mdoc in d:
|
| 95 | n += _DocCount(mdoc.doc)
|
| 96 | return n
|
| 97 |
|
| 98 | else:
|
| 99 | raise AssertionError()
|
| 100 |
|
| 101 |
|
| 102 | def _HNodePrettyPrint(perf_stats, doc_debug, node, f, max_width=80):
|
| 103 | # type: (bool, bool, hnode_t, mylib.Writer, int) -> None
|
| 104 |
|
| 105 | mylib.MaybeCollect()
|
| 106 | if perf_stats:
|
| 107 | log('___ HNODE COUNT %d', _HNodeCount(node))
|
| 108 | log('')
|
| 109 |
|
| 110 | if 0:
|
| 111 | log('___ GC: after hnode_t conversion')
|
| 112 | mylib.PrintGcStats()
|
| 113 | log('')
|
| 114 |
|
| 115 | enc = pp_hnode.HNodeEncoder()
|
| 116 | enc.SetUseStyles(f.isatty())
|
| 117 | enc.SetIndent(2) # save space, compared to 4 spaces
|
| 118 |
|
| 119 | d = enc.HNode(node)
|
| 120 |
|
| 121 | mylib.MaybeCollect()
|
| 122 | if perf_stats:
|
| 123 | if doc_debug:
|
| 124 | #if 0:
|
| 125 | # Pretty print the doc tree itself!
|
| 126 | p = d.PrettyTree(False)
|
| 127 | _HNodePrettyPrint(perf_stats, False, p, f)
|
| 128 |
|
| 129 | log('___ DOC COUNT %d', _DocCount(d))
|
| 130 | log('')
|
| 131 |
|
| 132 | if 0:
|
| 133 | log('___ GC: after doc_t conversion')
|
| 134 | mylib.PrintGcStats()
|
| 135 | log('')
|
| 136 |
|
| 137 | printer = pretty.PrettyPrinter(max_width) # max columns
|
| 138 |
|
| 139 | buf = mylib.BufWriter()
|
| 140 | printer.PrintDoc(d, buf)
|
| 141 |
|
| 142 | f.write(buf.getvalue())
|
| 143 | f.write('\n')
|
| 144 |
|
| 145 | mylib.MaybeCollect()
|
| 146 | if perf_stats:
|
| 147 | log('___ GC: after printing')
|
| 148 | mylib.PrintGcStats()
|
| 149 | log('')
|
| 150 |
|
| 151 |
|
| 152 | def HNodePrettyPrint(node, f, max_width=80):
|
| 153 | # type: (hnode_t, mylib.Writer, int) -> None
|
| 154 | """
|
| 155 | Make sure dependencies aren't a problem
|
| 156 | """
|
| 157 | _HNodePrettyPrint(False, True, node, f, max_width=max_width)
|