1.1 --- a/viewer.py Sun Oct 22 00:14:23 2006 +0200
1.2 +++ b/viewer.py Sun Oct 22 00:15:39 2006 +0200
1.3 @@ -120,7 +120,7 @@
1.4 .popup {
1.5 display: none; z-index: 2;
1.6 position: absolute; top: 1em; left: 0.5em;
1.7 - padding: 0.5em; background-color: #000000;
1.8 + padding: 0.2em; background-color: #000000;
1.9 }
1.10
1.11 .types {
1.12 @@ -154,16 +154,6 @@
1.13 </html>
1.14 """
1.15
1.16 -# Validation functions.
1.17 -
1.18 -def hasnode(fn):
1.19 - def _hasnode(self, node):
1.20 - if not hasattr(node, "_node"):
1.21 - return
1.22 - else:
1.23 - fn(self, node)
1.24 - return _hasnode
1.25 -
1.26 # Browser classes.
1.27
1.28 class Browser(ASTVisitor):
1.29 @@ -204,11 +194,18 @@
1.30 self.dispatch(node.expr)
1.31 self.stream.write("</div>\n")
1.32
1.33 + def visitAugAssign(self, node):
1.34 + self.stream.write("<div class='augassign'>\n")
1.35 + self.dispatch(node.node)
1.36 + self.stream.write("%s\n" % node.op)
1.37 + self.dispatch(node.expr)
1.38 + self.stream.write("</div>\n")
1.39 +
1.40 def visitClass(self, node):
1.41 definition = node._node
1.42 structure = definition.expr.ref
1.43 self.stream.write("<div class='class' id='%s'>\n" % self._url(structure.full_name()))
1.44 - self.stream.write("<p>\n")
1.45 + self.stream.write("<div>\n")
1.46 self._keyword("class")
1.47 self._name_start(structure.name)
1.48 self._popup_start()
1.49 @@ -232,7 +229,7 @@
1.50 self.stream.write(")")
1.51 self.stream.write(":\n")
1.52 self._comment(self._text(structure.full_name()))
1.53 - self.stream.write("</p>\n")
1.54 + self.stream.write("</div>\n")
1.55
1.56 self.stream.write("<div class='body'>\n")
1.57 self._doc(node)
1.58 @@ -240,13 +237,33 @@
1.59 self.stream.write("</div>\n")
1.60 self.stream.write("</div>\n")
1.61
1.62 - visitClass = hasnode(visitClass) # Remove unannotated nodes.
1.63 + def visitFor(self, node):
1.64 + self.stream.write("<div class='if'>\n")
1.65 + self.stream.write("<div>\n")
1.66 + self._keyword("for")
1.67 + self.dispatch(node.assign)
1.68 + self._keyword("in")
1.69 + self.dispatch(node.list)
1.70 + self.stream.write(":\n")
1.71 + self.stream.write("</div>\n")
1.72 + self.stream.write("<div class='body'>\n")
1.73 + self.dispatch(node.body)
1.74 + self.stream.write("</div>\n")
1.75 + if node.else_ is not None:
1.76 + self.stream.write("<div>\n")
1.77 + self._keyword("else")
1.78 + self.stream.write(":\n")
1.79 + self.stream.write("</div>\n")
1.80 + self.stream.write("<div class='body'>\n")
1.81 + self.dispatch(node.else_)
1.82 + self.stream.write("</div>\n")
1.83 + self.stream.write("</div>\n")
1.84
1.85 def visitFunction(self, node):
1.86 definition = node._node
1.87 subprogram = definition.expr.ref
1.88 - self.stream.write("<div class='def' id='%s'>\n" % self._url(subprogram.full_name()))
1.89 - self.stream.write("<p>\n")
1.90 + self.stream.write("<div class='function' id='%s'>\n" % self._url(subprogram.full_name()))
1.91 + self.stream.write("<div>\n")
1.92 self._keyword("def")
1.93 self._name_start(subprogram.name)
1.94 self._popup_start()
1.95 @@ -258,24 +275,24 @@
1.96 for param, default in subprogram.params:
1.97 if not first:
1.98 self.stream.write(",\n")
1.99 - self._parameter(subprogram, param)
1.100 + self._parameter(subprogram, param, default)
1.101 first = 0
1.102 if subprogram.star is not None:
1.103 if not first:
1.104 self.stream.write(", *\n")
1.105 param, default = subprogram.star
1.106 - self._parameter(subprogram, param)
1.107 + self._parameter(subprogram, param, default)
1.108 first = 0
1.109 if subprogram.dstar is not None:
1.110 if not first:
1.111 self.stream.write(", **\n")
1.112 param, default = subprogram.dstar
1.113 - self._parameter(subprogram, param)
1.114 + self._parameter(subprogram, param, default)
1.115 first = 0
1.116 self.stream.write(")")
1.117 self.stream.write(":\n")
1.118 self._comment(self._text(subprogram.full_name()))
1.119 - self.stream.write("</p>\n")
1.120 + self.stream.write("</div>\n")
1.121
1.122 self.stream.write("<div class='body'>\n")
1.123 self._doc(node)
1.124 @@ -283,14 +300,54 @@
1.125 self.stream.write("</div>\n")
1.126 self.stream.write("</div>\n")
1.127
1.128 - visitFunction = hasnode(visitFunction) # Remove unannotated nodes.
1.129 + def visitIf(self, node):
1.130 + self.stream.write("<div class='if'>\n")
1.131 + first = 1
1.132 + for compare, stmt in node.tests:
1.133 + self.stream.write("<div>\n")
1.134 + if first:
1.135 + self._keyword("if")
1.136 + else:
1.137 + self._keyword("elif")
1.138 + self.dispatch(compare)
1.139 + self.stream.write(":\n")
1.140 + self.stream.write("</div>\n")
1.141 + self.stream.write("<div class='body'>\n")
1.142 + self.dispatch(stmt)
1.143 + self.stream.write("</div>\n")
1.144 + first = 0
1.145 + if node.else_ is not None:
1.146 + self.stream.write("<div>\n")
1.147 + self._keyword("else")
1.148 + self.stream.write(":\n")
1.149 + self.stream.write("</div>\n")
1.150 + self.stream.write("<div class='body'>\n")
1.151 + self.dispatch(node.else_)
1.152 + self.stream.write("</div>\n")
1.153 + self.stream.write("</div>\n")
1.154
1.155 def visitPass(self, node):
1.156 + self.stream.write("<div class='pass'>\n")
1.157 self._keyword("pass")
1.158 + self.stream.write("</div>\n")
1.159 +
1.160 + def visitRaise(self, node):
1.161 + self.stream.write("<div class='raise'>\n")
1.162 + self._keyword("raise")
1.163 + self.dispatch(node.expr1)
1.164 + if node.expr2 is not None:
1.165 + self.stream.write(",\n")
1.166 + self.dispatch(node.expr2)
1.167 + if node.expr3 is not None:
1.168 + self.stream.write(",\n")
1.169 + self.dispatch(node.expr3)
1.170 + self.stream.write("</div>\n")
1.171
1.172 def visitReturn(self, node):
1.173 + self.stream.write("<div class='return'>\n")
1.174 self._keyword("return")
1.175 self.dispatch(node.value)
1.176 + self.stream.write("</div>\n")
1.177
1.178 def visitStmt(self, node):
1.179 self.stream.write("<div class='stmt'>\n")
1.180 @@ -299,6 +356,47 @@
1.181
1.182 # Expressions.
1.183
1.184 + def visitAssAttr(self, node):
1.185 + self.stream.write("<span class='assattr'>\n")
1.186 + self.dispatch(node.expr)
1.187 + self.stream.write("<span class='attr'>\n")
1.188 + self.stream.write(".%s\n" % self._text(node.attrname))
1.189 + if hasattr(node, "_node"):
1.190 + self._popup_start()
1.191 + self._types(node._node)
1.192 + self._scopes(node._node)
1.193 + self._popup_end()
1.194 + else:
1.195 + raise ValueError, node
1.196 + self.stream.write("</span>\n")
1.197 + self.stream.write("</span>\n")
1.198 +
1.199 + def visitAssList(self, node):
1.200 + self.stream.write("<span class='list'>\n")
1.201 + self.stream.write("[")
1.202 + self._sequence(node)
1.203 + self.stream.write("]\n")
1.204 + self.stream.write("</span>\n")
1.205 +
1.206 + def visitAssName(self, node):
1.207 + if hasattr(node, "_node"):
1.208 + self._name_start(node._node.name)
1.209 + self._popup_start()
1.210 + self._types(node._node.expr)
1.211 + self._scopes(node._node)
1.212 + self._popup_end()
1.213 + self._name_end()
1.214 + else:
1.215 + raise ValueError, node
1.216 + self._name(node.name)
1.217 +
1.218 + def visitAssTuple(self, node):
1.219 + self.stream.write("<span class='tuple'>\n")
1.220 + self.stream.write("(")
1.221 + self._sequence(node)
1.222 + self.stream.write(")\n")
1.223 + self.stream.write("</span>\n")
1.224 +
1.225 def visitCallFunc(self, node):
1.226 self.stream.write("<span class='callfunc'>\n")
1.227 self.dispatch(node.node)
1.228 @@ -322,46 +420,14 @@
1.229 self.stream.write(")\n")
1.230 self.stream.write("</span>\n")
1.231
1.232 - def visitTuple(self, node):
1.233 - self.stream.write("<span class='tuple'>\n")
1.234 - self.stream.write("(")
1.235 - self._sequence(node)
1.236 - self.stream.write(")\n")
1.237 - self.stream.write("</span>\n")
1.238 -
1.239 - visitAssTuple = visitTuple
1.240 -
1.241 - def visitList(self, node):
1.242 - self.stream.write("<span class='list'>\n")
1.243 - self.stream.write("[")
1.244 - self._sequence(node)
1.245 - self.stream.write("]\n")
1.246 + def visitCompare(self, node):
1.247 + self.stream.write("<span class='compare'>\n")
1.248 + self.dispatch(node.expr)
1.249 + for name, op in node.ops:
1.250 + self.stream.write("<span class='op'>%s</span>\n" % name)
1.251 + self.dispatch(op)
1.252 self.stream.write("</span>\n")
1.253
1.254 - visitAssList = visitList
1.255 -
1.256 - def visitName(self, node):
1.257 - if hasattr(node, "_node"):
1.258 - self._name_start(node._node.name)
1.259 - self._popup_start()
1.260 - self._types(node._node)
1.261 - self._scopes(node._node)
1.262 - self._popup_end()
1.263 - self._name_end()
1.264 - else:
1.265 - self._name(node.name)
1.266 -
1.267 - def visitAssName(self, node):
1.268 - if hasattr(node, "_node"):
1.269 - self._name_start(node._node.name)
1.270 - self._popup_start()
1.271 - self._types(node._node.expr)
1.272 - self._scopes(node._node)
1.273 - self._popup_end()
1.274 - self._name_end()
1.275 - else:
1.276 - self._name(node.name)
1.277 -
1.278 def visitConst(self, node):
1.279 self.stream.write(repr(node.value))
1.280
1.281 @@ -375,22 +441,60 @@
1.282 self._types(node._node)
1.283 self._scopes(node._node)
1.284 self._popup_end()
1.285 + else:
1.286 + raise ValueError, node
1.287 self.stream.write("</span>\n")
1.288 self.stream.write("</span>\n")
1.289
1.290 - def visitAssAttr(self, node):
1.291 - self.stream.write("<span class='assattr'>\n")
1.292 + def visitKeyword(self, node):
1.293 + self.stream.write("<span class='keyword'>\n")
1.294 + self.stream.write(node.name)
1.295 + self.stream.write("=")
1.296 self.dispatch(node.expr)
1.297 - self.stream.write("<span class='attr'>\n")
1.298 - self.stream.write(".%s\n" % self._text(node.attrname))
1.299 + self.stream.write("</span>\n")
1.300 +
1.301 + visitList = visitAssList
1.302 +
1.303 + def visitName(self, node):
1.304 if hasattr(node, "_node"):
1.305 + self._name_start(node._node.name)
1.306 self._popup_start()
1.307 self._types(node._node)
1.308 self._scopes(node._node)
1.309 self._popup_end()
1.310 + self._name_end()
1.311 + else:
1.312 + raise ValueError, node
1.313 + self._name(node.name)
1.314 +
1.315 + def visitSlice(self, node):
1.316 + self.stream.write("<span class='slice'>\n")
1.317 + self.dispatch(node.expr)
1.318 + self.stream.write("[")
1.319 + if node.lower:
1.320 + self.dispatch(node.lower)
1.321 + self.stream.write(":")
1.322 + if node.upper:
1.323 + self.dispatch(node.upper)
1.324 + # NOTE: Step?
1.325 + self.stream.write("]")
1.326 self.stream.write("</span>\n")
1.327 +
1.328 + def visitSubscript(self, node):
1.329 + self.stream.write("<span class='subscript'>\n")
1.330 + self.dispatch(node.expr)
1.331 + self.stream.write("[")
1.332 + first = 1
1.333 + for sub in node.subs:
1.334 + if not first:
1.335 + self.stream.write(", ")
1.336 + self.dispatch(sub)
1.337 + first = 0
1.338 + self.stream.write("]")
1.339 self.stream.write("</span>\n")
1.340
1.341 + visitTuple = visitAssTuple
1.342 +
1.343 # Output preparation methods.
1.344
1.345 def _text(self, text):
1.346 @@ -425,13 +529,16 @@
1.347 self.dispatch(n)
1.348 first = 0
1.349
1.350 - def _parameter(self, subprogram, param):
1.351 + def _parameter(self, subprogram, param, default):
1.352 self._name_start(param)
1.353 if hasattr(subprogram, "paramtypes"):
1.354 self._popup_start()
1.355 self._types_list(subprogram.paramtypes[param])
1.356 self._popup_end()
1.357 self._name_end()
1.358 + if default is not None and default.original is not None:
1.359 + self.stream.write("=\n")
1.360 + self.dispatch(default.original)
1.361
1.362 def _name(self, name):
1.363 self.stream.write("<span class='name'>%s</span>\n" % name)
1.364 @@ -457,7 +564,7 @@
1.365 self._types_list(flatten(node.accesses.values()))
1.366 else:
1.367 self.stream.write("<div class='types'>\n")
1.368 - self.stream.write("No types!\n")
1.369 + self.stream.write("unvisited\n")
1.370 self.stream.write("</div>\n")
1.371
1.372 def _types_list(self, types):
1.373 @@ -471,16 +578,14 @@
1.374
1.375 def _scopes(self, node):
1.376 if not isinstance(node, LoadName):
1.377 - self.stream.write("<div class='scopes'>\n")
1.378 - if not hasattr(node, "writes") and not hasattr(node, "accesses"):
1.379 - self.stream.write("No scopes!\n")
1.380 - else:
1.381 + if hasattr(node, "writes") or hasattr(node, "accesses"):
1.382 + self.stream.write("<div class='scopes'>\n")
1.383 for ref in getattr(node, "writes", getattr(node, "accesses", {})).keys():
1.384 fn = ref.full_name()
1.385 self.stream.write("<div class='scope'>")
1.386 self.stream.write(self._text(fn))
1.387 self.stream.write("</div>\n")
1.388 - self.stream.write("</div>\n")
1.389 + self.stream.write("</div>\n")
1.390
1.391 # Utility functions.
1.392