1.1 --- a/micropython/__init__.py Sat Jul 11 01:18:53 2009 +0200
1.2 +++ b/micropython/__init__.py Sat Jul 11 02:21:09 2009 +0200
1.3 @@ -446,7 +446,8 @@
1.4 # Include names which may not be explicitly used in programs.
1.5 # NOTE: Potentially declare these when inspecting.
1.6
1.7 - self.names_used = set(["__init__", "__call__", "__bool__"])
1.8 + self.names_used = None
1.9 + self.name_references = {}
1.10
1.11 # Status information.
1.12
1.13 @@ -498,11 +499,32 @@
1.14
1.15 # Name accounting.
1.16
1.17 - def use_name(self, name):
1.18 + def use_name(self, name, from_name):
1.19 +
1.20 + """
1.21 + Register the given 'name' as being used in the program from within an
1.22 + object with the specified 'from_name'.
1.23 + """
1.24 +
1.25 + if not self.name_references.has_key(from_name):
1.26 + self.name_references[from_name] = set()
1.27 + self.name_references[from_name].add(name)
1.28 +
1.29 + def uses_name(self, name):
1.30
1.31 - "Register the given 'name' as being used in the program."
1.32 + "Return whether the given 'name' is used."
1.33 +
1.34 + if self.names_used is None:
1.35 + self.names_used = set(["__init__", "__call__", "__bool__"])
1.36 + self._collect_names("__main__")
1.37
1.38 - self.names_used.add(name)
1.39 + return name in self.names_used
1.40 +
1.41 + def _collect_names(self, from_name):
1.42 + for name in self.name_references.get(from_name, []):
1.43 + if name not in self.names_used:
1.44 + self.names_used.add(name)
1.45 + self._collect_names(name)
1.46
1.47 # Constant accounting.
1.48
2.1 --- a/micropython/inspect.py Sat Jul 11 01:18:53 2009 +0200
2.2 +++ b/micropython/inspect.py Sat Jul 11 02:21:09 2009 +0200
2.3 @@ -228,7 +228,7 @@
2.4 # particular attribute and are unreferenced.
2.5
2.6 if obj_was_removed and isinstance(attr.get_value(), Function) and attr.get_value().is_method() or \
2.7 - name not in self.importer.names_used and \
2.8 + not self.importer.uses_name(name) and \
2.9 attr.assignments == 1 and isinstance(attr.get_value(), Function) and \
2.10 attr.get_value().is_method() and not attr.get_value().referenced:
2.11
2.12 @@ -317,6 +317,13 @@
2.13
2.14 return (self.namespaces[-1:] or [self])[0]
2.15
2.16 + def use_name(self, name):
2.17 +
2.18 + "Use the given 'name' within the current namespace/unit."
2.19 +
2.20 + unit = self.get_parent()
2.21 + self.importer.use_name(name, unit.name)
2.22 +
2.23 # Visitor methods.
2.24
2.25 def default(self, node, *args):
2.26 @@ -340,7 +347,7 @@
2.27 "Accounting method for the unary operator 'node'."
2.28
2.29 method = unary_methods[node.__class__.__name__]
2.30 - self.importer.use_name(method)
2.31 + self.use_name(method)
2.32 return self.OP(node)
2.33
2.34 def _visitBinary(self, node):
2.35 @@ -348,8 +355,8 @@
2.36 "Accounting method for the binary operator 'node'."
2.37
2.38 left_method, right_method = binary_methods[node.__class__.__name__]
2.39 - self.importer.use_name(left_method)
2.40 - self.importer.use_name(right_method)
2.41 + self.use_name(left_method)
2.42 + self.use_name(right_method)
2.43 return self.OP(node)
2.44
2.45 def _visitFunction(self, node, name):
2.46 @@ -454,7 +461,7 @@
2.47
2.48 # Declare names which will be used by generated code.
2.49
2.50 - self.importer.use_name("__getitem__")
2.51 + self.use_name("__getitem__")
2.52
2.53 # Process the assignment.
2.54
2.55 @@ -474,9 +481,9 @@
2.56 # Accounting.
2.57
2.58 aug_method, (left_method, right_method) = augassign_methods[node.op]
2.59 - self.importer.use_name(aug_method)
2.60 - self.importer.use_name(left_method)
2.61 - self.importer.use_name(right_method)
2.62 + self.use_name(aug_method)
2.63 + self.use_name(left_method)
2.64 + self.use_name(right_method)
2.65
2.66 # Process the assignment.
2.67
2.68 @@ -567,10 +574,10 @@
2.69 op_name, next_node = op
2.70 methods = comparison_methods[op_name]
2.71 if methods is not None:
2.72 - self.importer.use_name(methods[0])
2.73 - self.importer.use_name(methods[1])
2.74 + self.use_name(methods[0])
2.75 + self.use_name(methods[1])
2.76 elif op_name.endswith("in"):
2.77 - self.importer.use_name("__contains__")
2.78 + self.use_name("__contains__")
2.79
2.80 return self.OP(node)
2.81
2.82 @@ -602,8 +609,8 @@
2.83
2.84 # Declare names which will be used by generated code.
2.85
2.86 - self.importer.use_name("__iter__")
2.87 - self.importer.use_name("next")
2.88 + self.use_name("__iter__")
2.89 + self.use_name("next")
2.90
2.91 # Enter the loop.
2.92
2.93 @@ -676,7 +683,7 @@
2.94 if attr is not None:
2.95 attr.set_referenced()
2.96
2.97 - self.importer.use_name(attrname)
2.98 + self.use_name(attrname)
2.99
2.100 return attr
2.101
2.102 @@ -762,7 +769,7 @@
2.103 if attr is not None:
2.104 attr.set_referenced()
2.105
2.106 - self.importer.use_name(name)
2.107 + self.use_name(name)
2.108
2.109 return attr
2.110
2.111 @@ -796,7 +803,7 @@
2.112 visitSub = _visitBinary
2.113
2.114 def visitSubscript(self, node):
2.115 - self.importer.use_name("__getitem__")
2.116 + self.use_name("__getitem__")
2.117 self.OP(node)
2.118
2.119 def visitTryExcept(self, node):