1.1 --- a/viewer.py Sun Oct 22 01:43:53 2006 +0200
1.2 +++ b/viewer.py Sun Oct 22 02:57:22 2006 +0200
1.3 @@ -123,6 +123,11 @@
1.4 padding: 0.2em; background-color: #000000;
1.5 }
1.6
1.7 + .invocations {
1.8 + padding: 0.5em; background-color: #770000;
1.9 + clear: all;
1.10 + }
1.11 +
1.12 .types {
1.13 padding: 0.5em; background-color: #0000FF;
1.14 float: right;
1.15 @@ -133,12 +138,14 @@
1.16 float: left;
1.17 }
1.18
1.19 + .op,
1.20 .name,
1.21 .attr
1.22 {
1.23 position: relative;
1.24 }
1.25
1.26 + .op:hover > .popup,
1.27 .name:hover > .popup,
1.28 .attr:hover > .popup
1.29 {
1.30 @@ -160,6 +167,16 @@
1.31
1.32 """
1.33 A browsing visitor for AST nodes.
1.34 +
1.35 + Covered: AssAttr, AssList, AssName, AssTuple, Assign, AugAssign, Break,
1.36 + CallFunc, Class, Compare, Const, Continue, Dict, Discard, For,
1.37 + Function, Getattr, If, Keyword, Lambda, List, Module, Name, Pass, Raise, Return, Slice,
1.38 + Stmt, Subscript, Tuple, While.
1.39 +
1.40 + Missing: And, Add, Assert, Backquote, Bitand, Bitor, Bitxor, Decorators, Div,
1.41 + Ellipsis, Exec, FloorDiv, From, Global, Import, Invert, LeftShift, ListComp, ListCompFor,
1.42 + ListCompIf, Mod, Mul, Not, Or, Power, Print, Printnl, RightShift, Sliceobj,
1.43 + Sub, TryExcept, TryFinally, UnaryAdd, UnarySub, Yield.
1.44 """
1.45
1.46 def __init__(self, stream):
1.47 @@ -201,6 +218,11 @@
1.48 self.dispatch(node.expr)
1.49 self.stream.write("</div>\n")
1.50
1.51 + def visitBreak(self, node):
1.52 + self.stream.write("<div class='break'>\n")
1.53 + self._keyword("break")
1.54 + self.stream.write("</div>\n")
1.55 +
1.56 def visitClass(self, node):
1.57 definition = node._node
1.58 structure = definition.expr.ref
1.59 @@ -237,6 +259,11 @@
1.60 self.stream.write("</div>\n")
1.61 self.stream.write("</div>\n")
1.62
1.63 + def visitContinue(self, node):
1.64 + self.stream.write("<div class='continue'>\n")
1.65 + self._keyword("continue")
1.66 + self.stream.write("</div>\n")
1.67 +
1.68 def visitFor(self, node):
1.69 self.stream.write("<div class='if'>\n")
1.70 self.stream.write("<div>\n")
1.71 @@ -271,24 +298,7 @@
1.72 self._popup_end()
1.73 self._name_end()
1.74 self.stream.write("(")
1.75 - first = 1
1.76 - for param, default in subprogram.params:
1.77 - if not first:
1.78 - self.stream.write(",\n")
1.79 - self._parameter(subprogram, param, default)
1.80 - first = 0
1.81 - if subprogram.star is not None:
1.82 - if not first:
1.83 - self.stream.write(", *\n")
1.84 - param, default = subprogram.star
1.85 - self._parameter(subprogram, param, default)
1.86 - first = 0
1.87 - if subprogram.dstar is not None:
1.88 - if not first:
1.89 - self.stream.write(", **\n")
1.90 - param, default = subprogram.dstar
1.91 - self._parameter(subprogram, param, default)
1.92 - first = 0
1.93 + self._parameters(subprogram)
1.94 self.stream.write(")")
1.95 self.stream.write(":\n")
1.96 self._comment(self._text(subprogram.full_name()))
1.97 @@ -354,6 +364,26 @@
1.98 self.default(node)
1.99 self.stream.write("</div>\n")
1.100
1.101 + def visitWhile(self, node):
1.102 + self.stream.write("<div class='while'>\n")
1.103 + self.stream.write("<div>\n")
1.104 + self._keyword("while")
1.105 + self.dispatch(node.test)
1.106 + self.stream.write(":\n")
1.107 + self.stream.write("</div>\n")
1.108 + self.stream.write("<div class='body'>\n")
1.109 + self.dispatch(node.body)
1.110 + self.stream.write("</div>\n")
1.111 + if node.else_ is not None:
1.112 + self.stream.write("<div>\n")
1.113 + self._keyword("else")
1.114 + self.stream.write(":\n")
1.115 + self.stream.write("</div>\n")
1.116 + self.stream.write("<div class='body'>\n")
1.117 + self.dispatch(node.else_)
1.118 + self.stream.write("</div>\n")
1.119 + self.stream.write("</div>\n")
1.120 +
1.121 # Expressions.
1.122
1.123 def visitAssAttr(self, node):
1.124 @@ -423,9 +453,14 @@
1.125 def visitCompare(self, node):
1.126 self.stream.write("<span class='compare'>\n")
1.127 self.dispatch(node.expr)
1.128 - for name, op in node.ops:
1.129 - self.stream.write("<span class='op'>%s</span>\n" % name)
1.130 - self.dispatch(op)
1.131 + for (op_name, expr), _op in map(None, node.ops, node._ops):
1.132 + self.stream.write("<span class='op'>\n")
1.133 + self.stream.write(op_name)
1.134 + self._popup_start()
1.135 + self._op(op_name, _op)
1.136 + self._popup_end()
1.137 + self.stream.write("</span>\n")
1.138 + self.dispatch(expr)
1.139 self.stream.write("</span>\n")
1.140
1.141 def visitConst(self, node):
1.142 @@ -453,6 +488,15 @@
1.143 self.dispatch(node.expr)
1.144 self.stream.write("</span>\n")
1.145
1.146 + def visitLambda(self, node):
1.147 + definition = node._node
1.148 + subprogram = definition.expr.ref
1.149 + self.stream.write("<span class='lambda'>\n")
1.150 + self._keyword("lambda")
1.151 + self._parameters(subprogram)
1.152 + self.dispatch(node.code)
1.153 + self.stream.write("</span>\n")
1.154 +
1.155 visitList = visitAssList
1.156
1.157 def visitName(self, node):
1.158 @@ -529,6 +573,26 @@
1.159 self.dispatch(n)
1.160 first = 0
1.161
1.162 + def _parameters(self, subprogram):
1.163 + first = 1
1.164 + for param, default in subprogram.params:
1.165 + if not first:
1.166 + self.stream.write(",\n")
1.167 + self._parameter(subprogram, param, default)
1.168 + first = 0
1.169 + if subprogram.star is not None:
1.170 + if not first:
1.171 + self.stream.write(", *\n")
1.172 + param, default = subprogram.star
1.173 + self._parameter(subprogram, param, default)
1.174 + first = 0
1.175 + if subprogram.dstar is not None:
1.176 + if not first:
1.177 + self.stream.write(", **\n")
1.178 + param, default = subprogram.dstar
1.179 + self._parameter(subprogram, param, default)
1.180 + first = 0
1.181 +
1.182 def _parameter(self, subprogram, param, default):
1.183 self._name_start(param)
1.184 if hasattr(subprogram, "paramtypes"):
1.185 @@ -555,6 +619,23 @@
1.186 def _popup_end(self):
1.187 self.stream.write("</span>\n")
1.188
1.189 + def _op(self, op_name, op):
1.190 + if op is not None:
1.191 + self._invocations(op)
1.192 +
1.193 + def _invocations(self, node):
1.194 + if hasattr(node, "invocations"):
1.195 + self._invocations_list(node.invocations)
1.196 +
1.197 + def _invocations_list(self, invocations):
1.198 + self.stream.write("<div class='invocations'>\n")
1.199 + for invocation in invocations:
1.200 + fn = invocation.full_name()
1.201 + self.stream.write("<div class='invocation'>")
1.202 + self.stream.write(self._text(fn))
1.203 + self.stream.write("</div>\n")
1.204 + self.stream.write("</div>\n")
1.205 +
1.206 def _types(self, node):
1.207 if hasattr(node, "types"):
1.208 self._types_list(node.types)