1.1 --- a/micropython/__init__.py Sun Feb 27 17:38:50 2011 +0100
1.2 +++ b/micropython/__init__.py Sun Mar 13 20:58:54 2011 +0100
1.3 @@ -377,6 +377,13 @@
1.4 self.attributes_used = set()
1.5 self.name_references = {}
1.6 self.specific_name_references = {}
1.7 +
1.8 + # Attribute coverage calculated during collection.
1.9 +
1.10 + self.inferred_name_references = {}
1.11 +
1.12 + # Attribute coverage status during collection.
1.13 +
1.14 self.attribute_users_visited = set()
1.15 self.attributes_to_visit = {}
1.16
1.17 @@ -537,11 +544,26 @@
1.18 self.attributes_to_visit[objname] = set()
1.19 self.attributes_to_visit[objname].add(attrname)
1.20
1.21 + def _collect_attributes_from(self, from_name, objname, attrname, objtable):
1.22 +
1.23 + """
1.24 + Record the association between 'from_name' and the attribute of
1.25 + 'objname' with the given 'attrname'. Then collect attributes for the
1.26 + referenced attribute using 'objtable'.
1.27 + """
1.28 +
1.29 + if not self.inferred_name_references.has_key(from_name):
1.30 + self.inferred_name_references[from_name] = set()
1.31 +
1.32 + self.inferred_name_references[from_name].add((objname, attrname))
1.33 + self._collect_attributes(objname + "." + attrname, objtable)
1.34 +
1.35 def _collect_attributes(self, from_name, objtable):
1.36
1.37 """
1.38 Given an object called 'from_name', find all names referenced from such
1.39 - an object according to the register of names.
1.40 + an object according to the register of names, using 'objtable' to infer
1.41 + types.
1.42 """
1.43
1.44 if from_name in self.attribute_users_visited:
1.45 @@ -588,7 +610,7 @@
1.46
1.47 if objname in self.attributes_used:
1.48 self.use_attribute(objname, attrname)
1.49 - self._collect_attributes(objname + "." + attrname, objtable)
1.50 + self._collect_attributes_from(from_name, objname, attrname, objtable)
1.51
1.52 # Record attributes of other objects for potential visiting.
1.53
1.54 @@ -599,7 +621,7 @@
1.55
1.56 for objname, attrname in self.specific_name_references.get(from_name, []):
1.57 self.use_attribute(objname, attrname)
1.58 - self._collect_attributes(objname + "." + attrname, objtable)
1.59 + self._collect_attributes_from(from_name, objname, attrname, objtable)
1.60
1.61 # Where the object has an __init__ attribute, assume that it is an
1.62 # initialiser which is called at some point, and collect attributes used
1.63 @@ -607,7 +629,7 @@
1.64
1.65 if "__init__" in objtable.table.get(from_name, []):
1.66 self.use_attribute(from_name, "__init__")
1.67 - self._collect_attributes(from_name + ".__init__", objtable)
1.68 + self._collect_attributes_from(from_name, from_name, "__init__", objtable)
1.69
1.70 # Visit attributes on this object that were queued in case of the object
1.71 # being referenced.
1.72 @@ -619,7 +641,7 @@
1.73
1.74 for attrname in attributes_to_visit:
1.75 self.use_attribute(from_name, attrname)
1.76 - self._collect_attributes(from_name + "." + attrname, objtable)
1.77 + self._collect_attributes_from(from_name, from_name, attrname, objtable)
1.78
1.79 # Constant accounting.
1.80