# HG changeset patch # User Paul Boddie # Date 1339285791 -7200 # Node ID 897aa8ac47290e75911b55c034723c4a8a8cea58 # Parent bbcb39c672017374935ee925613021f2c16c86d0 Introduced attribute target reporting with links to attribute definitions. diff -r bbcb39c67201 -r 897aa8ac4729 micropython/report.py --- a/micropython/report.py Sat Jun 09 23:24:18 2012 +0200 +++ b/micropython/report.py Sun Jun 10 01:49:51 2012 +0200 @@ -76,6 +76,7 @@ z-index: 3; } + .attributes-popup, .types-popup { display: none; position: absolute; @@ -91,6 +92,7 @@ color: white; } + .attr, .accessor, .name, .operation { @@ -99,6 +101,7 @@ color: white; } + .attr:hover, .accessor:hover, .name:hover, .operation:hover { @@ -108,6 +111,7 @@ z-index: 2; } + .attr:hover .attributes-popup, .accessor:hover .types-popup, .name:hover .popup, .operation:hover .popup { @@ -122,6 +126,7 @@ background-color: #700; } + .attrnames a, .opnames a { color: white; } @@ -304,20 +309,26 @@ if trailing: self.stream.write(" ") + def _names_list_start(self, label, classes): + self.stream.write("
%s
" % (classes, label)) + + def _names_list_end(self): + self.stream.write("
\n") + def _names_list(self, names, label, classes): if not names: return names = list(names) names.sort() - self.stream.write("
%s
" % (classes, label)) + self._names_list_start(label, classes) first = 1 for name in names: if not first: self.stream.write("
") self.stream.write(name) first = 0 - self.stream.write("
\n") + self._names_list_end() def _attrcombined(self, name, node): attrcombined = hasattr(node, "_attrcombined") and node._attrcombined.get(name) or [] @@ -354,6 +365,59 @@ if target_names: self._span_end() + def _attribute_start(self, attrname, attributes): + if attributes: + attributes.sort(key=lambda t: t[2]) + + self._span_start("attr") + self._popup_start("attributes-popup") + self._names_list_start("attributes", "attrnames") + + # Mix links to attributes with labels indicating undetermined + # attributes. + + last = None + for value, target, target_name in attributes: + if value and not isinstance(value, Instance): + fullname = value.full_name() + current = (value, fullname) + if current != last: + if last is not None: + self.stream.write("
") + self._object_name_ref(value.module, value, fullname, classes="attribute-name") + else: + fullname = target_name + "." + attrname + current = (None, fullname) + if current != last: + if last is not None: + self.stream.write("
") + self.stream.write(fullname) + last = current + + self._names_list_end() + self._popup_end() + + def _attribute_end(self, attributes): + if attributes: + self._span_end() + + def _get_attributes(self, possible_types, attrname): + objtable = self.program.get_object_table() + attributes = [] + for target_name, is_static in possible_types: + target = objtable.get_object(target_name) + try: + attr = objtable.access(target_name, attrname) + except TableError: + continue + if attr.is_static_attribute(): + for v in attr.get_values(): + attributes.append((v, target, target_name)) + else: + attributes.append((None, target, target_name)) + + return attributes + # Summary classes. class Summary(Writer): @@ -510,8 +574,6 @@ self.visitor = self self.module = module self.program = program - self.objtable = self.program.get_object_table() - self.paramtable = self.program.get_parameter_table() def to_stream(self, stream): @@ -918,16 +980,19 @@ self._span_end() def visitAssAttr(self, node): + possible_types = self.possible_accessor_types(node, defining_users=0) target_names = ["%s%s" % (is_static and "static " or "", target_name) - for target_name, is_static in self.possible_accessor_types(node, defining_users=0)] + for target_name, is_static in possible_types] + attributes = self._get_attributes(possible_types, node.attrname) + self._span_start("assattr") self._accessor_start(target_names) self.dispatch(node.expr) self._accessor_end(target_names) - self._span_start("attr") self.stream.write(".") + self._attribute_start(node.attrname, attributes) self._span(node.attrname, "attrname" + (not target_names and " no-targets" or "")) - self._span_end() + self._attribute_end(attributes) self._span_end() def visitAssList(self, node): @@ -1010,16 +1075,19 @@ self._visitBinary(node, "floordiv", "//") def visitGetattr(self, node): + possible_types = self.possible_accessor_types(node, defining_users=0) target_names = ["%s%s" % (is_static and "static " or "", target_name) - for target_name, is_static in self.possible_accessor_types(node, defining_users=0)] + for target_name, is_static in possible_types] + attributes = self._get_attributes(possible_types, node.attrname) + self._span_start("getattr") self._accessor_start(target_names) self.dispatch(node.expr) self._accessor_end(target_names) - self._span_start("attr") self.stream.write(".") + self._attribute_start(node.attrname, attributes) self._span(node.attrname, "attrname" + (not target_names and " no-targets" or "")) - self._span_end() + self._attribute_end(attributes) self._span_end() def visitGenExpr(self, node):