1.1 --- a/micropython/__init__.py Tue Jun 15 00:50:51 2010 +0200
1.2 +++ b/micropython/__init__.py Wed Jun 16 01:08:18 2010 +0200
1.3 @@ -370,6 +370,7 @@
1.4 self.name_references = {}
1.5 self.specific_name_references = {}
1.6 self.attribute_users_visited = set()
1.7 + self.attributes_to_visit = {}
1.8
1.9 # Status information.
1.10
1.11 @@ -484,22 +485,35 @@
1.12
1.13 self.attributes_used.add(objname + "." + name)
1.14
1.15 + def use_object(self, objname):
1.16 +
1.17 + "Indicate that the object with the given 'objname' is used."
1.18 +
1.19 + self.attributes_used.add(objname)
1.20 +
1.21 def collect_attributes(self, objtable):
1.22
1.23 "Collect attribute references for the entire program."
1.24
1.25 + # Include names which may not be explicitly used in programs.
1.26 + # NOTE: Potentially declare these when inspecting.
1.27 +
1.28 + for attrname in self.names_always_used:
1.29 + for objname in objtable.all_possible_objects([attrname]):
1.30 +
1.31 + # Record attributes of objects for potential visiting.
1.32 +
1.33 + self.add_attribute_to_visit(objname, attrname)
1.34 +
1.35 # Start with the "root" modules, finding referenced objects.
1.36
1.37 self._collect_attributes("__builtins__", objtable)
1.38 self._collect_attributes("__main__", objtable)
1.39
1.40 - # Include names which may not be explicitly used in programs.
1.41 - # NOTE: Potentially declare these when inspecting.
1.42 -
1.43 - for attrname in self.names_always_used:
1.44 - for objname in objtable.all_possible_objects([attrname]):
1.45 - self.use_attribute(objname, attrname)
1.46 - self._collect_attributes(objname + "." + attrname, objtable)
1.47 + def add_attribute_to_visit(self, objname, attrname):
1.48 + if not self.attributes_to_visit.has_key(objname):
1.49 + self.attributes_to_visit[objname] = set()
1.50 + self.attributes_to_visit[objname].add(attrname)
1.51
1.52 def _collect_attributes(self, from_name, objtable):
1.53
1.54 @@ -524,10 +538,22 @@
1.55 if not objnames:
1.56 print "Warning: usage in %r finds no object supporting any attributes %r" % (from_name, names)
1.57
1.58 + # For each suggested object, consider each attribute given by the
1.59 + # names.
1.60 +
1.61 for objname in objnames:
1.62 for name in names:
1.63 - self.use_attribute(objname, name)
1.64 - self._collect_attributes(objname + "." + name, objtable)
1.65 +
1.66 + # Visit attributes of objects known to be used.
1.67 +
1.68 + if objname in self.attributes_used:
1.69 + self.use_attribute(objname, name)
1.70 + self._collect_attributes(objname + "." + name, objtable)
1.71 +
1.72 + # Record attributes of other objects for potential visiting.
1.73 +
1.74 + else:
1.75 + self.add_attribute_to_visit(objname, name)
1.76
1.77 # Get specific name references and visit the referenced objects.
1.78
1.79 @@ -543,6 +569,17 @@
1.80 self.use_attribute(from_name, "__init__")
1.81 self._collect_attributes(from_name + ".__init__", objtable)
1.82
1.83 + # Visit attributes on objects not previously visited.
1.84 +
1.85 + attributes_to_visit = self.attributes_to_visit.get(from_name, [])
1.86 +
1.87 + if attributes_to_visit:
1.88 + del self.attributes_to_visit[from_name]
1.89 +
1.90 + for attrname in attributes_to_visit:
1.91 + self.use_attribute(from_name, attrname)
1.92 + self._collect_attributes(from_name + "." + attrname, objtable)
1.93 +
1.94 # Constant accounting.
1.95
1.96 def init_predefined_constants(self):
1.97 @@ -763,6 +800,7 @@
1.98
1.99 # Record the module.
1.100
1.101 + self.use_object(module.full_name())
1.102 #print "Loaded", module_name, "with namespace", module.namespace.keys()
1.103 return module
1.104