1.1 --- a/micropython/__init__.py Sat Nov 08 21:47:26 2008 +0100
1.2 +++ b/micropython/__init__.py Sat Nov 08 23:09:48 2008 +0100
1.3 @@ -94,11 +94,25 @@
1.4 self.constant_list = None # cache for constants
1.5 self.init_predefined_constants()
1.6
1.7 + # Name records (used to track actual use of names).
1.8 +
1.9 + self.names_used = set()
1.10 +
1.11 # Main program information.
1.12
1.13 self.code = None
1.14 self.code_location = None
1.15
1.16 + # Name accounting.
1.17 +
1.18 + def use_name(self, name):
1.19 +
1.20 + "Register the given 'name' as being used in the program."
1.21 +
1.22 + self.names_used.add(name)
1.23 +
1.24 + # Constant accounting.
1.25 +
1.26 def init_predefined_constants(self):
1.27
1.28 "Ensure the predefined constants."
1.29 @@ -136,6 +150,8 @@
1.30
1.31 return self.constant_list
1.32
1.33 + # General maintenance.
1.34 +
1.35 def vacuum(self):
1.36
1.37 "Tidy up the modules."
1.38 @@ -160,6 +176,8 @@
1.39 if isinstance(obj, (micropython.inspect.Class, micropython.inspect.Function)):
1.40 obj.finalise_attributes()
1.41
1.42 + # Access to finalised program information.
1.43 +
1.44 def get_modules(self):
1.45
1.46 "Return all modules known to the importer."
2.1 --- a/micropython/inspect.py Sat Nov 08 21:47:26 2008 +0100
2.2 +++ b/micropython/inspect.py Sat Nov 08 23:09:48 2008 +0100
2.3 @@ -150,9 +150,9 @@
2.4 del self[name]
2.5
2.6 # Remove unreferenced names.
2.7 - # NOTE: This, due to the nature of the referenced attribute, assumes
2.8 - # NOTE: that only explicitly mentioned classes and functions are
2.9 - # NOTE: employed in the final program.
2.10 + # This, due to the nature of the referenced attribute, assumes
2.11 + # that only explicitly mentioned classes and functions are
2.12 + # employed in the final program.
2.13
2.14 elif self.should_optimise_unused_objects():
2.15
2.16 @@ -526,22 +526,28 @@
2.17
2.18 def visitGetattr(self, node):
2.19 expr = self.dispatch(node.expr)
2.20 + attrname = node.attrname
2.21 +
2.22 if isinstance(expr, Attr):
2.23 value = expr.value
2.24 if isinstance(value, (Class, Module)):
2.25 - attr = value.namespace.get(node.attrname)
2.26 + attr = value.namespace.get(attrname)
2.27 elif isinstance(value, UnresolvedName):
2.28 - attr = UnresolvedName(node.attrname, value.full_name(), self)
2.29 + attr = UnresolvedName(attrname, value.full_name(), self)
2.30 else:
2.31 attr = None
2.32 elif self.builtins is not None:
2.33 - attr = self.builtins.get(node.attrname)
2.34 + attr = self.builtins.get(attrname)
2.35 else:
2.36 - attr = UnresolvedName(node.attrname, value.full_name(), self)
2.37 + attr = UnresolvedName(attrname, value.full_name(), self)
2.38 +
2.39 + # Accounting.
2.40
2.41 if attr is not None:
2.42 attr.set_referenced()
2.43
2.44 + self.importer.use_name(attrname)
2.45 +
2.46 return attr
2.47
2.48 def visitGlobal(self, node):
2.49 @@ -609,6 +615,7 @@
2.50
2.51 def visitName(self, node):
2.52 name = node.name
2.53 +
2.54 if self.importer.predefined_constants.has_key(name):
2.55 attr = self.importer.get_predefined_constant(name)
2.56 elif self.namespaces and self.namespaces[-1].has_key(name):
2.57 @@ -620,9 +627,13 @@
2.58 else:
2.59 attr = None
2.60
2.61 + # Accounting.
2.62 +
2.63 if attr is not None:
2.64 attr.set_referenced()
2.65
2.66 + self.importer.use_name(name)
2.67 +
2.68 return attr
2.69
2.70 visitNot = OP