1.1 --- a/micropython/common.py Sun Apr 28 19:23:05 2013 +0200
1.2 +++ b/micropython/common.py Sun Apr 28 19:56:18 2013 +0200
1.3 @@ -86,7 +86,7 @@
1.4 try:
1.5 attributes.add(self.objtable.access(target.full_name(), attrname))
1.6 except TableError:
1.7 - return None
1.8 + pass
1.9
1.10 return attributes
1.11
1.12 @@ -129,47 +129,6 @@
1.13
1.14 return False
1.15
1.16 - def possible_accessor_types(self, node, defining_users=1):
1.17 -
1.18 - """
1.19 - Given annotations made during the inspection process, return all possible
1.20 - type names and indications of static usage for a 'node' involved in
1.21 - attribute access.
1.22 -
1.23 - If 'defining_users' is set to a false value, attempt to get the type
1.24 - names specifically applicable to the node, rather than retrieving more
1.25 - general definition-based type observations.
1.26 - """
1.27 -
1.28 - all_target_names = []
1.29 -
1.30 - # Where an attribute could already be detected and where its nature is
1.31 - # not that of a general instance or an unresolved name, attempt to
1.32 - # identify it.
1.33 -
1.34 - # Use explicit annotations on the node.
1.35 -
1.36 - attrs = self.possible_attributes_from_annotation(node)
1.37 - if attrs:
1.38 - target_names = set()
1.39 - for (attr, value) in attrs:
1.40 - # NOTE: Ignoring constant objects.
1.41 - if attr:
1.42 - target_names.add((attr.parent.full_name(), attr.is_static_attribute()))
1.43 - all_target_names.append(target_names)
1.44 -
1.45 - # Use attribute usage observations.
1.46 -
1.47 - target_names = self.possible_accessor_types_from_usage(node, defining_users)
1.48 - if target_names:
1.49 - all_target_names.append(target_names)
1.50 -
1.51 - # Return the smallest set of target names.
1.52 -
1.53 - all_target_names.sort(key=lambda x: len(x))
1.54 -
1.55 - return all_target_names and all_target_names[0]
1.56 -
1.57 def possible_attributes_from_annotation(self, node):
1.58
1.59 """
2.1 --- a/micropython/report.py Sun Apr 28 19:23:05 2013 +0200
2.2 +++ b/micropython/report.py Sun Apr 28 19:56:18 2013 +0200
2.3 @@ -3,7 +3,7 @@
2.4 """
2.5 View annotated sources.
2.6
2.7 -Copyright (C) 2006, 2007, 2010, 2011, 2012 Paul Boddie <paul@boddie.org.uk>
2.8 +Copyright (C) 2006, 2007, 2010, 2011, 2012, 2013 Paul Boddie <paul@boddie.org.uk>
2.9
2.10 This program is free software; you can redistribute it and/or modify it under
2.11 the terms of the GNU General Public License as published by the Free Software
2.12 @@ -345,7 +345,7 @@
2.13 for name in names:
2.14 if not first:
2.15 self.stream.write("<br />")
2.16 - self.stream.write(name)
2.17 + self.stream.write(self._text(name))
2.18 first = False
2.19 self._names_list_end()
2.20
2.21 @@ -419,17 +419,39 @@
2.22 values.sort()
2.23 return values
2.24
2.25 - def _attributes_to_attribute_names(self, attributes, attrname):
2.26 + def _attribute_value_to_name(self, attr, value, target=False):
2.27 + if value and not isinstance(value, Instance):
2.28 + fullname = value.full_name()
2.29 + elif isinstance(attr.parent, Instance):
2.30 + fullname = "%s%s" % (attr.parent_type.full_name(), not target and ".%s" % attr.name or "")
2.31 + else:
2.32 + fullname = "%s%s" % (attr.parent.full_name(), not target and ".%s" % attr.name or "")
2.33 + return fullname
2.34 +
2.35 + def _attributes_to_target_names(self, attributes):
2.36 +
2.37 + "Get the target names for the 'attributes'."
2.38 +
2.39 + output = []
2.40 +
2.41 + if attributes:
2.42 + for attr, value in attributes:
2.43 + fullname = self._attribute_value_to_name(attr, value, True)
2.44 + output.append(fullname)
2.45 +
2.46 + output.sort()
2.47 + return output
2.48 +
2.49 + def _attributes_to_attribute_names(self, attributes):
2.50
2.51 "Get the output form of the 'attributes'."
2.52
2.53 output = []
2.54 - for value, target, target_name in attributes:
2.55 - if value and not isinstance(value, Instance):
2.56 - fullname = value.full_name()
2.57 - else:
2.58 - fullname = target_name + "." + attrname
2.59 - output.append((fullname, value))
2.60 +
2.61 + if attributes:
2.62 + for attr, value in attributes:
2.63 + fullname = self._attribute_value_to_name(attr, value, False)
2.64 + output.append((fullname, value))
2.65
2.66 output.sort()
2.67 return output
2.68 @@ -1049,34 +1071,36 @@
2.69 first = False
2.70 self._span_end()
2.71
2.72 - def visitAssAttr(self, node):
2.73 - possible_types = self.possible_accessor_types(node, defining_users=0)
2.74 -
2.75 - # Record whether types were already deduced. If not, get types using
2.76 - # only this attribute.
2.77 + def _visitAttr(self, node, label):
2.78 + self.record_unknown_targets(node)
2.79
2.80 - deduced = possible_types
2.81 - if not possible_types:
2.82 - possible_types = self._get_possible_types(node.attrname)
2.83 + attributes = node._value_deduced and [self.get_attribute_and_value(node._value_deduced)] or \
2.84 + node._attr_deduced and [self.get_attribute_and_value(node._attr_deduced)] or \
2.85 + node._attrs_deduced or \
2.86 + map(self.get_attribute_and_value, node._attrs_deduced_from_specific_usage or [])
2.87
2.88 - self.record_unknown_targets(possible_types, deduced, node)
2.89 - attributes = self._get_attributes(possible_types, node.attrname)
2.90 + possible_types = self._attributes_to_target_names(attributes)
2.91
2.92 wraps_getattr = self._has_descendant(node.expr, compiler.ast.Getattr)
2.93
2.94 if not wraps_getattr:
2.95 - self._span_start("assattr")
2.96 + self._span_start(label)
2.97 self._accessor_start(possible_types)
2.98 self.dispatch(node.expr)
2.99 if not wraps_getattr:
2.100 self._accessor_end(possible_types)
2.101 +
2.102 self.stream.write(".")
2.103 - self._attribute_start(node.attrname, self._attributes_to_attribute_names(attributes, node.attrname))
2.104 - self._span(node.attrname, "attrname" + (not possible_types and " no-targets" or not deduced and " any-target" or ""))
2.105 + self._attribute_start(node.attrname, self._attributes_to_attribute_names(attributes))
2.106 + self._span(node.attrname, "attrname" + (not possible_types and " no-targets" or ""))
2.107 self._attribute_end(attributes)
2.108 +
2.109 if not wraps_getattr:
2.110 self._span_end()
2.111
2.112 + def visitAssAttr(self, node):
2.113 + self._visitAttr(node, "assattr")
2.114 +
2.115 def visitAssList(self, node):
2.116 self._span_start("list")
2.117 self.stream.write("[")
2.118 @@ -1157,37 +1181,7 @@
2.119 self._visitBinary(node, "//")
2.120
2.121 def visitGetattr(self, node):
2.122 - possible_types = self.possible_accessor_types(node, defining_users=0)
2.123 -
2.124 - # Record whether types were already deduced. If not, get types using
2.125 - # only this attribute.
2.126 -
2.127 - deduced = possible_types
2.128 - if not possible_types:
2.129 - possible_types = self._get_possible_types(node.attrname)
2.130 -
2.131 - self.record_unknown_targets(possible_types, deduced, node)
2.132 - attributes = self._get_attributes(possible_types, node.attrname)
2.133 -
2.134 - wraps_getattr = self._has_descendant(node.expr, compiler.ast.Getattr)
2.135 -
2.136 - if not wraps_getattr:
2.137 - self._span_start("getattr")
2.138 - self._accessor_start(possible_types)
2.139 -
2.140 - self.dispatch(node.expr)
2.141 -
2.142 - if not wraps_getattr:
2.143 - self._accessor_end(possible_types)
2.144 -
2.145 - self.stream.write(".")
2.146 -
2.147 - self._attribute_start(node.attrname, self._attributes_to_attribute_names(attributes, node.attrname))
2.148 - self._span(node.attrname, "attrname" + (not possible_types and " no-targets" or not deduced and " any-target" or ""))
2.149 - self._attribute_end(attributes)
2.150 -
2.151 - if not wraps_getattr:
2.152 - self._span_end()
2.153 + self._visitAttr(node, "getattr")
2.154
2.155 def visitGenExpr(self, node):
2.156 self._span_start("genexpr")
2.157 @@ -1458,13 +1452,10 @@
2.158
2.159 # Statistics gathering methods.
2.160
2.161 - def possible_accessor_types(self, node, defining_users=1):
2.162 - return set([tn for (tn, st) in ASTVisitor.possible_accessor_types(self, node, defining_users)])
2.163 -
2.164 - def record_unknown_targets(self, possible_types, deduced, node):
2.165 - if not possible_types:
2.166 + def record_unknown_targets(self, node):
2.167 + if not node._attrs_deduced:
2.168 self.program.unknown_target_nodes.append((self.units[-1], node))
2.169 - elif not deduced:
2.170 + elif not node._attrs_deduced_from_specific_usage:
2.171 self.program.independent_target_nodes.append((self.units[-1], node))
2.172
2.173 # Utility methods.