# HG changeset patch # User paulb@jeremy # Date 1161468939 -7200 # Node ID 35cc8355b7f9411da31fa708f8f1df73a3ab4932 # Parent 70396fe4115ca79aef262f1582ef6cf71b884805 Reordered node handlers. Expanded node coverage. Introduced default parameter values and keyword node support. diff -r 70396fe4115c -r 35cc8355b7f9 viewer.py --- a/viewer.py Sun Oct 22 00:14:23 2006 +0200 +++ b/viewer.py Sun Oct 22 00:15:39 2006 +0200 @@ -120,7 +120,7 @@ .popup { display: none; z-index: 2; position: absolute; top: 1em; left: 0.5em; - padding: 0.5em; background-color: #000000; + padding: 0.2em; background-color: #000000; } .types { @@ -154,16 +154,6 @@ """ -# Validation functions. - -def hasnode(fn): - def _hasnode(self, node): - if not hasattr(node, "_node"): - return - else: - fn(self, node) - return _hasnode - # Browser classes. class Browser(ASTVisitor): @@ -204,11 +194,18 @@ self.dispatch(node.expr) self.stream.write("\n") + def visitAugAssign(self, node): + self.stream.write("
\n") + self.dispatch(node.node) + self.stream.write("%s\n" % node.op) + self.dispatch(node.expr) + self.stream.write("
\n") + def visitClass(self, node): definition = node._node structure = definition.expr.ref self.stream.write("
\n" % self._url(structure.full_name())) - self.stream.write("

\n") + self.stream.write("

\n") self._keyword("class") self._name_start(structure.name) self._popup_start() @@ -232,7 +229,7 @@ self.stream.write(")") self.stream.write(":\n") self._comment(self._text(structure.full_name())) - self.stream.write("

\n") + self.stream.write("
\n") self.stream.write("
\n") self._doc(node) @@ -240,13 +237,33 @@ self.stream.write("
\n") self.stream.write("
\n") - visitClass = hasnode(visitClass) # Remove unannotated nodes. + def visitFor(self, node): + self.stream.write("
\n") + self.stream.write("
\n") + self._keyword("for") + self.dispatch(node.assign) + self._keyword("in") + self.dispatch(node.list) + self.stream.write(":\n") + self.stream.write("
\n") + self.stream.write("
\n") + self.dispatch(node.body) + self.stream.write("
\n") + if node.else_ is not None: + self.stream.write("
\n") + self._keyword("else") + self.stream.write(":\n") + self.stream.write("
\n") + self.stream.write("
\n") + self.dispatch(node.else_) + self.stream.write("
\n") + self.stream.write("
\n") def visitFunction(self, node): definition = node._node subprogram = definition.expr.ref - self.stream.write("
\n" % self._url(subprogram.full_name())) - self.stream.write("

\n") + self.stream.write("

\n" % self._url(subprogram.full_name())) + self.stream.write("
\n") self._keyword("def") self._name_start(subprogram.name) self._popup_start() @@ -258,24 +275,24 @@ for param, default in subprogram.params: if not first: self.stream.write(",\n") - self._parameter(subprogram, param) + self._parameter(subprogram, param, default) first = 0 if subprogram.star is not None: if not first: self.stream.write(", *\n") param, default = subprogram.star - self._parameter(subprogram, param) + self._parameter(subprogram, param, default) first = 0 if subprogram.dstar is not None: if not first: self.stream.write(", **\n") param, default = subprogram.dstar - self._parameter(subprogram, param) + self._parameter(subprogram, param, default) first = 0 self.stream.write(")") self.stream.write(":\n") self._comment(self._text(subprogram.full_name())) - self.stream.write("

\n") + self.stream.write("
\n") self.stream.write("
\n") self._doc(node) @@ -283,14 +300,54 @@ self.stream.write("
\n") self.stream.write("
\n") - visitFunction = hasnode(visitFunction) # Remove unannotated nodes. + def visitIf(self, node): + self.stream.write("
\n") + first = 1 + for compare, stmt in node.tests: + self.stream.write("
\n") + if first: + self._keyword("if") + else: + self._keyword("elif") + self.dispatch(compare) + self.stream.write(":\n") + self.stream.write("
\n") + self.stream.write("
\n") + self.dispatch(stmt) + self.stream.write("
\n") + first = 0 + if node.else_ is not None: + self.stream.write("
\n") + self._keyword("else") + self.stream.write(":\n") + self.stream.write("
\n") + self.stream.write("
\n") + self.dispatch(node.else_) + self.stream.write("
\n") + self.stream.write("
\n") def visitPass(self, node): + self.stream.write("
\n") self._keyword("pass") + self.stream.write("
\n") + + def visitRaise(self, node): + self.stream.write("
\n") + self._keyword("raise") + self.dispatch(node.expr1) + if node.expr2 is not None: + self.stream.write(",\n") + self.dispatch(node.expr2) + if node.expr3 is not None: + self.stream.write(",\n") + self.dispatch(node.expr3) + self.stream.write("
\n") def visitReturn(self, node): + self.stream.write("
\n") self._keyword("return") self.dispatch(node.value) + self.stream.write("
\n") def visitStmt(self, node): self.stream.write("
\n") @@ -299,6 +356,47 @@ # Expressions. + def visitAssAttr(self, node): + self.stream.write("\n") + self.dispatch(node.expr) + self.stream.write("\n") + self.stream.write(".%s\n" % self._text(node.attrname)) + if hasattr(node, "_node"): + self._popup_start() + self._types(node._node) + self._scopes(node._node) + self._popup_end() + else: + raise ValueError, node + self.stream.write("\n") + self.stream.write("\n") + + def visitAssList(self, node): + self.stream.write("\n") + self.stream.write("[") + self._sequence(node) + self.stream.write("]\n") + self.stream.write("\n") + + def visitAssName(self, node): + if hasattr(node, "_node"): + self._name_start(node._node.name) + self._popup_start() + self._types(node._node.expr) + self._scopes(node._node) + self._popup_end() + self._name_end() + else: + raise ValueError, node + self._name(node.name) + + def visitAssTuple(self, node): + self.stream.write("\n") + self.stream.write("(") + self._sequence(node) + self.stream.write(")\n") + self.stream.write("\n") + def visitCallFunc(self, node): self.stream.write("\n") self.dispatch(node.node) @@ -322,46 +420,14 @@ self.stream.write(")\n") self.stream.write("\n") - def visitTuple(self, node): - self.stream.write("\n") - self.stream.write("(") - self._sequence(node) - self.stream.write(")\n") - self.stream.write("\n") - - visitAssTuple = visitTuple - - def visitList(self, node): - self.stream.write("\n") - self.stream.write("[") - self._sequence(node) - self.stream.write("]\n") + def visitCompare(self, node): + self.stream.write("\n") + self.dispatch(node.expr) + for name, op in node.ops: + self.stream.write("%s\n" % name) + self.dispatch(op) self.stream.write("\n") - visitAssList = visitList - - def visitName(self, node): - if hasattr(node, "_node"): - self._name_start(node._node.name) - self._popup_start() - self._types(node._node) - self._scopes(node._node) - self._popup_end() - self._name_end() - else: - self._name(node.name) - - def visitAssName(self, node): - if hasattr(node, "_node"): - self._name_start(node._node.name) - self._popup_start() - self._types(node._node.expr) - self._scopes(node._node) - self._popup_end() - self._name_end() - else: - self._name(node.name) - def visitConst(self, node): self.stream.write(repr(node.value)) @@ -375,22 +441,60 @@ self._types(node._node) self._scopes(node._node) self._popup_end() + else: + raise ValueError, node self.stream.write("\n") self.stream.write("\n") - def visitAssAttr(self, node): - self.stream.write("\n") + def visitKeyword(self, node): + self.stream.write("\n") + self.stream.write(node.name) + self.stream.write("=") self.dispatch(node.expr) - self.stream.write("\n") - self.stream.write(".%s\n" % self._text(node.attrname)) + self.stream.write("\n") + + visitList = visitAssList + + def visitName(self, node): if hasattr(node, "_node"): + self._name_start(node._node.name) self._popup_start() self._types(node._node) self._scopes(node._node) self._popup_end() + self._name_end() + else: + raise ValueError, node + self._name(node.name) + + def visitSlice(self, node): + self.stream.write("\n") + self.dispatch(node.expr) + self.stream.write("[") + if node.lower: + self.dispatch(node.lower) + self.stream.write(":") + if node.upper: + self.dispatch(node.upper) + # NOTE: Step? + self.stream.write("]") self.stream.write("\n") + + def visitSubscript(self, node): + self.stream.write("\n") + self.dispatch(node.expr) + self.stream.write("[") + first = 1 + for sub in node.subs: + if not first: + self.stream.write(", ") + self.dispatch(sub) + first = 0 + self.stream.write("]") self.stream.write("\n") + visitTuple = visitAssTuple + # Output preparation methods. def _text(self, text): @@ -425,13 +529,16 @@ self.dispatch(n) first = 0 - def _parameter(self, subprogram, param): + def _parameter(self, subprogram, param, default): self._name_start(param) if hasattr(subprogram, "paramtypes"): self._popup_start() self._types_list(subprogram.paramtypes[param]) self._popup_end() self._name_end() + if default is not None and default.original is not None: + self.stream.write("=\n") + self.dispatch(default.original) def _name(self, name): self.stream.write("%s\n" % name) @@ -457,7 +564,7 @@ self._types_list(flatten(node.accesses.values())) else: self.stream.write("
\n") - self.stream.write("No types!\n") + self.stream.write("unvisited\n") self.stream.write("
\n") def _types_list(self, types): @@ -471,16 +578,14 @@ def _scopes(self, node): if not isinstance(node, LoadName): - self.stream.write("
\n") - if not hasattr(node, "writes") and not hasattr(node, "accesses"): - self.stream.write("No scopes!\n") - else: + if hasattr(node, "writes") or hasattr(node, "accesses"): + self.stream.write("
\n") for ref in getattr(node, "writes", getattr(node, "accesses", {})).keys(): fn = ref.full_name() self.stream.write("
") self.stream.write(self._text(fn)) self.stream.write("
\n") - self.stream.write("
\n") + self.stream.write("
\n") # Utility functions.