1.1 --- a/micropython/report.py Sat Jun 09 23:24:18 2012 +0200
1.2 +++ b/micropython/report.py Sun Jun 10 01:49:51 2012 +0200
1.3 @@ -76,6 +76,7 @@
1.4 z-index: 3;
1.5 }
1.6
1.7 + .attributes-popup,
1.8 .types-popup {
1.9 display: none;
1.10 position: absolute;
1.11 @@ -91,6 +92,7 @@
1.12 color: white;
1.13 }
1.14
1.15 + .attr,
1.16 .accessor,
1.17 .name,
1.18 .operation {
1.19 @@ -99,6 +101,7 @@
1.20 color: white;
1.21 }
1.22
1.23 + .attr:hover,
1.24 .accessor:hover,
1.25 .name:hover,
1.26 .operation:hover {
1.27 @@ -108,6 +111,7 @@
1.28 z-index: 2;
1.29 }
1.30
1.31 + .attr:hover .attributes-popup,
1.32 .accessor:hover .types-popup,
1.33 .name:hover .popup,
1.34 .operation:hover .popup {
1.35 @@ -122,6 +126,7 @@
1.36 background-color: #700;
1.37 }
1.38
1.39 + .attrnames a,
1.40 .opnames a {
1.41 color: white;
1.42 }
1.43 @@ -304,20 +309,26 @@
1.44 if trailing:
1.45 self.stream.write(" ")
1.46
1.47 + def _names_list_start(self, label, classes):
1.48 + self.stream.write("<div class='%s'><span class='label'>%s</span><br />" % (classes, label))
1.49 +
1.50 + def _names_list_end(self):
1.51 + self.stream.write("</div>\n")
1.52 +
1.53 def _names_list(self, names, label, classes):
1.54 if not names:
1.55 return
1.56 names = list(names)
1.57 names.sort()
1.58
1.59 - self.stream.write("<div class='%s'><span class='label'>%s</span><br />" % (classes, label))
1.60 + self._names_list_start(label, classes)
1.61 first = 1
1.62 for name in names:
1.63 if not first:
1.64 self.stream.write("<br />")
1.65 self.stream.write(name)
1.66 first = 0
1.67 - self.stream.write("</div>\n")
1.68 + self._names_list_end()
1.69
1.70 def _attrcombined(self, name, node):
1.71 attrcombined = hasattr(node, "_attrcombined") and node._attrcombined.get(name) or []
1.72 @@ -354,6 +365,59 @@
1.73 if target_names:
1.74 self._span_end()
1.75
1.76 + def _attribute_start(self, attrname, attributes):
1.77 + if attributes:
1.78 + attributes.sort(key=lambda t: t[2])
1.79 +
1.80 + self._span_start("attr")
1.81 + self._popup_start("attributes-popup")
1.82 + self._names_list_start("attributes", "attrnames")
1.83 +
1.84 + # Mix links to attributes with labels indicating undetermined
1.85 + # attributes.
1.86 +
1.87 + last = None
1.88 + for value, target, target_name in attributes:
1.89 + if value and not isinstance(value, Instance):
1.90 + fullname = value.full_name()
1.91 + current = (value, fullname)
1.92 + if current != last:
1.93 + if last is not None:
1.94 + self.stream.write("<br />")
1.95 + self._object_name_ref(value.module, value, fullname, classes="attribute-name")
1.96 + else:
1.97 + fullname = target_name + "." + attrname
1.98 + current = (None, fullname)
1.99 + if current != last:
1.100 + if last is not None:
1.101 + self.stream.write("<br />")
1.102 + self.stream.write(fullname)
1.103 + last = current
1.104 +
1.105 + self._names_list_end()
1.106 + self._popup_end()
1.107 +
1.108 + def _attribute_end(self, attributes):
1.109 + if attributes:
1.110 + self._span_end()
1.111 +
1.112 + def _get_attributes(self, possible_types, attrname):
1.113 + objtable = self.program.get_object_table()
1.114 + attributes = []
1.115 + for target_name, is_static in possible_types:
1.116 + target = objtable.get_object(target_name)
1.117 + try:
1.118 + attr = objtable.access(target_name, attrname)
1.119 + except TableError:
1.120 + continue
1.121 + if attr.is_static_attribute():
1.122 + for v in attr.get_values():
1.123 + attributes.append((v, target, target_name))
1.124 + else:
1.125 + attributes.append((None, target, target_name))
1.126 +
1.127 + return attributes
1.128 +
1.129 # Summary classes.
1.130
1.131 class Summary(Writer):
1.132 @@ -510,8 +574,6 @@
1.133 self.visitor = self
1.134 self.module = module
1.135 self.program = program
1.136 - self.objtable = self.program.get_object_table()
1.137 - self.paramtable = self.program.get_parameter_table()
1.138
1.139 def to_stream(self, stream):
1.140
1.141 @@ -918,16 +980,19 @@
1.142 self._span_end()
1.143
1.144 def visitAssAttr(self, node):
1.145 + possible_types = self.possible_accessor_types(node, defining_users=0)
1.146 target_names = ["%s%s" % (is_static and "static " or "", target_name)
1.147 - for target_name, is_static in self.possible_accessor_types(node, defining_users=0)]
1.148 + for target_name, is_static in possible_types]
1.149 + attributes = self._get_attributes(possible_types, node.attrname)
1.150 +
1.151 self._span_start("assattr")
1.152 self._accessor_start(target_names)
1.153 self.dispatch(node.expr)
1.154 self._accessor_end(target_names)
1.155 - self._span_start("attr")
1.156 self.stream.write(".")
1.157 + self._attribute_start(node.attrname, attributes)
1.158 self._span(node.attrname, "attrname" + (not target_names and " no-targets" or ""))
1.159 - self._span_end()
1.160 + self._attribute_end(attributes)
1.161 self._span_end()
1.162
1.163 def visitAssList(self, node):
1.164 @@ -1010,16 +1075,19 @@
1.165 self._visitBinary(node, "floordiv", "//")
1.166
1.167 def visitGetattr(self, node):
1.168 + possible_types = self.possible_accessor_types(node, defining_users=0)
1.169 target_names = ["%s%s" % (is_static and "static " or "", target_name)
1.170 - for target_name, is_static in self.possible_accessor_types(node, defining_users=0)]
1.171 + for target_name, is_static in possible_types]
1.172 + attributes = self._get_attributes(possible_types, node.attrname)
1.173 +
1.174 self._span_start("getattr")
1.175 self._accessor_start(target_names)
1.176 self.dispatch(node.expr)
1.177 self._accessor_end(target_names)
1.178 - self._span_start("attr")
1.179 self.stream.write(".")
1.180 + self._attribute_start(node.attrname, attributes)
1.181 self._span(node.attrname, "attrname" + (not target_names and " no-targets" or ""))
1.182 - self._span_end()
1.183 + self._attribute_end(attributes)
1.184 self._span_end()
1.185
1.186 def visitGenExpr(self, node):