1.1 --- a/viewer.py Mon Oct 16 00:36:34 2006 +0200
1.2 +++ b/viewer.py Mon Oct 16 00:39:44 2006 +0200
1.3 @@ -22,8 +22,19 @@
1.4 """
1.5
1.6 from compiler.visitor import ASTVisitor
1.7 +from simplified import *
1.8 import sys
1.9
1.10 +# Exceptions.
1.11 +
1.12 +class ViewerError(SimplifiedError):
1.13 +
1.14 + "An error in viewing."
1.15 +
1.16 + pass
1.17 +
1.18 +# Classes.
1.19 +
1.20 class Viewer(ASTVisitor):
1.21
1.22 """
1.23 @@ -100,16 +111,14 @@
1.24 .body { padding-left: 2em; }
1.25 .keyword { color: yellow; }
1.26 .comment { color: blue; }
1.27 + .str { color: #FF00FF; }
1.28 + .doc { color: #FF00FF; margin-bottom: 1em; }
1.29 .ref { color: cyan; }
1.30 .ref a { color: cyan; text-decoration: none; }
1.31
1.32 - .name {
1.33 - position: relative;
1.34 - }
1.35 -
1.36 .types {
1.37 display: none; z-index: 2;
1.38 - position: absolute; top: 1em; left: 6.5em;
1.39 + position: absolute; top: 1em; left: 7.5em;
1.40 padding: 0.5em; background-color: #0000FF;
1.41 }
1.42
1.43 @@ -119,8 +128,16 @@
1.44 padding: 0.5em; background-color: #007700;
1.45 }
1.46
1.47 + .name,
1.48 + .attr
1.49 + {
1.50 + position: relative;
1.51 + }
1.52 +
1.53 .name:hover > .types,
1.54 - .name:hover > .scopes
1.55 + .name:hover > .scopes,
1.56 + .attr:hover > .types,
1.57 + .attr:hover > .scopes
1.58 {
1.59 display: block;
1.60 }
1.61 @@ -150,6 +167,15 @@
1.62 self.dispatch(module)
1.63 self.stream.write(html_footer)
1.64
1.65 + def dispatch(self, node):
1.66 + try:
1.67 + ASTVisitor.dispatch(self, node)
1.68 + except ViewerError, exc:
1.69 + exc.add(node)
1.70 + raise
1.71 + except Exception, exc:
1.72 + raise ViewerError(exc, node)
1.73 +
1.74 def visitModule(self, node):
1.75 self.default(node)
1.76
1.77 @@ -160,11 +186,11 @@
1.78
1.79 def visitClass(self, node):
1.80 definition = node._node
1.81 - structure = definition.expr.types[0].type
1.82 + structure = definition.expr.ref
1.83 self.stream.write("<div class='class' id='%s'>\n" % self._url(structure.full_name()))
1.84 self.stream.write("<p>\n")
1.85 self._keyword("class")
1.86 - self._name_start(structure)
1.87 + self._name_start(structure.name)
1.88 self._scopes(definition)
1.89 self._name_end()
1.90 bases = structure.bases
1.91 @@ -174,7 +200,7 @@
1.92 for base in bases:
1.93 if not first:
1.94 self.stream.write(",\n")
1.95 - self._name_start(base)
1.96 + self._name_start(base.name)
1.97 self._types(base)
1.98 self._scopes(base)
1.99 self._name_end()
1.100 @@ -190,6 +216,41 @@
1.101 self.stream.write("</div>\n")
1.102 self.stream.write("</div>\n")
1.103
1.104 + def visitFunction(self, node):
1.105 + definition = node._node
1.106 + subprogram = definition.expr.ref
1.107 + self.stream.write("<div class='def' id='%s'>\n" % self._url(subprogram.full_name()))
1.108 + self.stream.write("<p>\n")
1.109 + self._keyword("def")
1.110 + self._name_start(subprogram.name)
1.111 + self._scopes(definition)
1.112 + self._name_end()
1.113 + self.stream.write("(")
1.114 + first = 1
1.115 + for param, default in subprogram.params:
1.116 + if not first:
1.117 + self.stream.write(",\n")
1.118 + self._name_start(param)
1.119 + if hasattr(subprogram, "paramtypes"):
1.120 + self._types_list(subprogram.paramtypes[param])
1.121 + self._name_end()
1.122 + first = 0
1.123 + self.stream.write(")")
1.124 + self.stream.write(":\n")
1.125 + self._comment(self._text(subprogram.full_name()))
1.126 + self.stream.write("</p>\n")
1.127 +
1.128 + self.stream.write("<div class='body'>\n")
1.129 + self._doc(node)
1.130 + self.dispatch(node.code)
1.131 + self.stream.write("</div>\n")
1.132 + self.stream.write("</div>\n")
1.133 +
1.134 + def visitStmt(self, node):
1.135 + self.stream.write("<div class='stmt'>\n")
1.136 + self.default(node)
1.137 + self.stream.write("</div>\n")
1.138 +
1.139 def visitAssign(self, node):
1.140 self.stream.write("<div class='assign'>\n")
1.141 for lvalue in node.nodes:
1.142 @@ -219,13 +280,13 @@
1.143 visitAssList = visitList
1.144
1.145 def visitName(self, node):
1.146 - self._name_start(node._node)
1.147 + self._name_start(node._node.name)
1.148 self._types(node._node)
1.149 self._scopes(node._node)
1.150 self._name_end()
1.151
1.152 def visitAssName(self, node):
1.153 - self._name_start(node._node)
1.154 + self._name_start(node._node.name)
1.155 self._types(node._node.expr)
1.156 self._scopes(node._node)
1.157 self._name_end()
1.158 @@ -233,6 +294,26 @@
1.159 def visitConst(self, node):
1.160 self.stream.write(repr(node.value))
1.161
1.162 + def visitGetattr(self, node):
1.163 + self.stream.write("<span class='getattr'>\n")
1.164 + self.dispatch(node.expr)
1.165 + self.stream.write("<span class='attr'>\n")
1.166 + self.stream.write(".%s\n" % self._text(node.attrname))
1.167 + self._types(node._node)
1.168 + self._scopes(node._node)
1.169 + self.stream.write("</span>\n")
1.170 + self.stream.write("</span>\n")
1.171 +
1.172 + def visitAssAttr(self, node):
1.173 + self.stream.write("<span class='assattr'>\n")
1.174 + self.dispatch(node.expr)
1.175 + self.stream.write("<span class='attr'>\n")
1.176 + self.stream.write(".%s\n" % self._text(node.attrname))
1.177 + self._types(node._node)
1.178 + self._scopes(node._node)
1.179 + self.stream.write("</span>\n")
1.180 + self.stream.write("</span>\n")
1.181 +
1.182 # Output preparation methods.
1.183
1.184 def _text(self, text):
1.185 @@ -252,7 +333,7 @@
1.186
1.187 def _doc(self, node):
1.188 if node.doc is not None:
1.189 - self.stream.write("<div class='doc'>%s</div>\n" % self._text(node.doc))
1.190 + self.stream.write("<div class='doc'>%s</div>\n" % self._text(repr(node.doc)))
1.191
1.192 def _sequence(self, node):
1.193 first = 1
1.194 @@ -262,18 +343,26 @@
1.195 self.dispatch(n)
1.196 first = 0
1.197
1.198 - def _name(self, node):
1.199 - self.stream.write("<span class='name'>%s</span>\n" % node.name)
1.200 + def _name(self, name):
1.201 + self.stream.write("<span class='name'>%s</span>\n" % name)
1.202
1.203 - def _name_start(self, node):
1.204 - self.stream.write("<span class='name'>%s\n" % node.name)
1.205 + def _name_start(self, name):
1.206 + self.stream.write("<span class='name'>%s\n" % name)
1.207
1.208 def _name_end(self):
1.209 self.stream.write("</span>\n")
1.210
1.211 def _types(self, node):
1.212 + if not hasattr(node, "types"):
1.213 + self.stream.write("<div class='types'>\n")
1.214 + self.stream.write("No types!\n")
1.215 + self.stream.write("</div>\n")
1.216 + else:
1.217 + self._types_list(node.types)
1.218 +
1.219 + def _types_list(self, types):
1.220 self.stream.write("<div class='types'>\n")
1.221 - for type in node.types:
1.222 + for type in types:
1.223 fn = type.type.full_name()
1.224 self.stream.write("<div class='type'>")
1.225 self.stream.write(self._text(fn))
1.226 @@ -281,15 +370,17 @@
1.227 self.stream.write("</div>\n")
1.228
1.229 def _scopes(self, node):
1.230 - self.stream.write("<div class='scopes'>\n")
1.231 - if not hasattr(node, "writes") and not hasattr(node, "accesses"):
1.232 - raise AttributeError, node
1.233 - for ref in getattr(node, "writes", getattr(node, "accesses", {})).keys():
1.234 - fn = ref.full_name()
1.235 - self.stream.write("<div class='scope'>")
1.236 - self.stream.write(self._text(fn))
1.237 + if not isinstance(node, LoadName):
1.238 + self.stream.write("<div class='scopes'>\n")
1.239 + if not hasattr(node, "writes") and not hasattr(node, "accesses"):
1.240 + self.stream.write("No scopes!\n")
1.241 + else:
1.242 + for ref in getattr(node, "writes", getattr(node, "accesses", {})).keys():
1.243 + fn = ref.full_name()
1.244 + self.stream.write("<div class='scope'>")
1.245 + self.stream.write(self._text(fn))
1.246 + self.stream.write("</div>\n")
1.247 self.stream.write("</div>\n")
1.248 - self.stream.write("</div>\n")
1.249
1.250 # Convenience functions.
1.251