2.1 --- a/viewer.py Sun Oct 22 01:43:53 2006 +0200
2.2 +++ b/viewer.py Sun Oct 22 02:57:22 2006 +0200
2.3 @@ -123,6 +123,11 @@
2.4 padding: 0.2em; background-color: #000000;
2.5 }
2.6
2.7 + .invocations {
2.8 + padding: 0.5em; background-color: #770000;
2.9 + clear: all;
2.10 + }
2.11 +
2.12 .types {
2.13 padding: 0.5em; background-color: #0000FF;
2.14 float: right;
2.15 @@ -133,12 +138,14 @@
2.16 float: left;
2.17 }
2.18
2.19 + .op,
2.20 .name,
2.21 .attr
2.22 {
2.23 position: relative;
2.24 }
2.25
2.26 + .op:hover > .popup,
2.27 .name:hover > .popup,
2.28 .attr:hover > .popup
2.29 {
2.30 @@ -160,6 +167,16 @@
2.31
2.32 """
2.33 A browsing visitor for AST nodes.
2.34 +
2.35 + Covered: AssAttr, AssList, AssName, AssTuple, Assign, AugAssign, Break,
2.36 + CallFunc, Class, Compare, Const, Continue, Dict, Discard, For,
2.37 + Function, Getattr, If, Keyword, Lambda, List, Module, Name, Pass, Raise, Return, Slice,
2.38 + Stmt, Subscript, Tuple, While.
2.39 +
2.40 + Missing: And, Add, Assert, Backquote, Bitand, Bitor, Bitxor, Decorators, Div,
2.41 + Ellipsis, Exec, FloorDiv, From, Global, Import, Invert, LeftShift, ListComp, ListCompFor,
2.42 + ListCompIf, Mod, Mul, Not, Or, Power, Print, Printnl, RightShift, Sliceobj,
2.43 + Sub, TryExcept, TryFinally, UnaryAdd, UnarySub, Yield.
2.44 """
2.45
2.46 def __init__(self, stream):
2.47 @@ -201,6 +218,11 @@
2.48 self.dispatch(node.expr)
2.49 self.stream.write("</div>\n")
2.50
2.51 + def visitBreak(self, node):
2.52 + self.stream.write("<div class='break'>\n")
2.53 + self._keyword("break")
2.54 + self.stream.write("</div>\n")
2.55 +
2.56 def visitClass(self, node):
2.57 definition = node._node
2.58 structure = definition.expr.ref
2.59 @@ -237,6 +259,11 @@
2.60 self.stream.write("</div>\n")
2.61 self.stream.write("</div>\n")
2.62
2.63 + def visitContinue(self, node):
2.64 + self.stream.write("<div class='continue'>\n")
2.65 + self._keyword("continue")
2.66 + self.stream.write("</div>\n")
2.67 +
2.68 def visitFor(self, node):
2.69 self.stream.write("<div class='if'>\n")
2.70 self.stream.write("<div>\n")
2.71 @@ -271,24 +298,7 @@
2.72 self._popup_end()
2.73 self._name_end()
2.74 self.stream.write("(")
2.75 - first = 1
2.76 - for param, default in subprogram.params:
2.77 - if not first:
2.78 - self.stream.write(",\n")
2.79 - self._parameter(subprogram, param, default)
2.80 - first = 0
2.81 - if subprogram.star is not None:
2.82 - if not first:
2.83 - self.stream.write(", *\n")
2.84 - param, default = subprogram.star
2.85 - self._parameter(subprogram, param, default)
2.86 - first = 0
2.87 - if subprogram.dstar is not None:
2.88 - if not first:
2.89 - self.stream.write(", **\n")
2.90 - param, default = subprogram.dstar
2.91 - self._parameter(subprogram, param, default)
2.92 - first = 0
2.93 + self._parameters(subprogram)
2.94 self.stream.write(")")
2.95 self.stream.write(":\n")
2.96 self._comment(self._text(subprogram.full_name()))
2.97 @@ -354,6 +364,26 @@
2.98 self.default(node)
2.99 self.stream.write("</div>\n")
2.100
2.101 + def visitWhile(self, node):
2.102 + self.stream.write("<div class='while'>\n")
2.103 + self.stream.write("<div>\n")
2.104 + self._keyword("while")
2.105 + self.dispatch(node.test)
2.106 + self.stream.write(":\n")
2.107 + self.stream.write("</div>\n")
2.108 + self.stream.write("<div class='body'>\n")
2.109 + self.dispatch(node.body)
2.110 + self.stream.write("</div>\n")
2.111 + if node.else_ is not None:
2.112 + self.stream.write("<div>\n")
2.113 + self._keyword("else")
2.114 + self.stream.write(":\n")
2.115 + self.stream.write("</div>\n")
2.116 + self.stream.write("<div class='body'>\n")
2.117 + self.dispatch(node.else_)
2.118 + self.stream.write("</div>\n")
2.119 + self.stream.write("</div>\n")
2.120 +
2.121 # Expressions.
2.122
2.123 def visitAssAttr(self, node):
2.124 @@ -423,9 +453,14 @@
2.125 def visitCompare(self, node):
2.126 self.stream.write("<span class='compare'>\n")
2.127 self.dispatch(node.expr)
2.128 - for name, op in node.ops:
2.129 - self.stream.write("<span class='op'>%s</span>\n" % name)
2.130 - self.dispatch(op)
2.131 + for (op_name, expr), _op in map(None, node.ops, node._ops):
2.132 + self.stream.write("<span class='op'>\n")
2.133 + self.stream.write(op_name)
2.134 + self._popup_start()
2.135 + self._op(op_name, _op)
2.136 + self._popup_end()
2.137 + self.stream.write("</span>\n")
2.138 + self.dispatch(expr)
2.139 self.stream.write("</span>\n")
2.140
2.141 def visitConst(self, node):
2.142 @@ -453,6 +488,15 @@
2.143 self.dispatch(node.expr)
2.144 self.stream.write("</span>\n")
2.145
2.146 + def visitLambda(self, node):
2.147 + definition = node._node
2.148 + subprogram = definition.expr.ref
2.149 + self.stream.write("<span class='lambda'>\n")
2.150 + self._keyword("lambda")
2.151 + self._parameters(subprogram)
2.152 + self.dispatch(node.code)
2.153 + self.stream.write("</span>\n")
2.154 +
2.155 visitList = visitAssList
2.156
2.157 def visitName(self, node):
2.158 @@ -529,6 +573,26 @@
2.159 self.dispatch(n)
2.160 first = 0
2.161
2.162 + def _parameters(self, subprogram):
2.163 + first = 1
2.164 + for param, default in subprogram.params:
2.165 + if not first:
2.166 + self.stream.write(",\n")
2.167 + self._parameter(subprogram, param, default)
2.168 + first = 0
2.169 + if subprogram.star is not None:
2.170 + if not first:
2.171 + self.stream.write(", *\n")
2.172 + param, default = subprogram.star
2.173 + self._parameter(subprogram, param, default)
2.174 + first = 0
2.175 + if subprogram.dstar is not None:
2.176 + if not first:
2.177 + self.stream.write(", **\n")
2.178 + param, default = subprogram.dstar
2.179 + self._parameter(subprogram, param, default)
2.180 + first = 0
2.181 +
2.182 def _parameter(self, subprogram, param, default):
2.183 self._name_start(param)
2.184 if hasattr(subprogram, "paramtypes"):
2.185 @@ -555,6 +619,23 @@
2.186 def _popup_end(self):
2.187 self.stream.write("</span>\n")
2.188
2.189 + def _op(self, op_name, op):
2.190 + if op is not None:
2.191 + self._invocations(op)
2.192 +
2.193 + def _invocations(self, node):
2.194 + if hasattr(node, "invocations"):
2.195 + self._invocations_list(node.invocations)
2.196 +
2.197 + def _invocations_list(self, invocations):
2.198 + self.stream.write("<div class='invocations'>\n")
2.199 + for invocation in invocations:
2.200 + fn = invocation.full_name()
2.201 + self.stream.write("<div class='invocation'>")
2.202 + self.stream.write(self._text(fn))
2.203 + self.stream.write("</div>\n")
2.204 + self.stream.write("</div>\n")
2.205 +
2.206 def _types(self, node):
2.207 if hasattr(node, "types"):
2.208 self._types_list(node.types)