1.1 --- a/annotate.py Sun Oct 29 18:43:29 2006 +0100
1.2 +++ b/annotate.py Sun Oct 29 18:44:17 2006 +0100
1.3 @@ -123,6 +123,7 @@
1.4 self.subprograms = []
1.5 self.current_subprograms = []
1.6 self.current_namespaces = []
1.7 + self.namespace = None
1.8
1.9 # Give constants their own namespace.
1.10
1.11 @@ -149,6 +150,11 @@
1.12 mutate nodes in the original program.
1.13 """
1.14
1.15 + # Record the current subprogram and namespace.
1.16 +
1.17 + self.current_subprograms.append(node)
1.18 + self.current_namespaces.append(self.namespace)
1.19 +
1.20 # Determine the namespace.
1.21
1.22 if locals is not None:
1.23 @@ -156,11 +162,6 @@
1.24 else:
1.25 self.namespace = self.global_namespace
1.26
1.27 - # Record the current subprogram and namespace.
1.28 -
1.29 - self.current_subprograms.append(node)
1.30 - self.current_namespaces.append(self.namespace)
1.31 -
1.32 # Add namespace details to any structure involved.
1.33
1.34 if getattr(node, "structure", None) is not None:
1.35 @@ -188,10 +189,7 @@
1.36
1.37 # Restore the previous subprogram and namespace.
1.38
1.39 - self.current_namespaces.pop()
1.40 - if self.current_namespaces:
1.41 - self.namespace = self.current_namespaces[-1]
1.42 -
1.43 + self.namespace = self.current_namespaces.pop()
1.44 self.current_subprograms.pop()
1.45
1.46 return result
1.47 @@ -214,15 +212,7 @@
1.48 handler.
1.49 """
1.50
1.51 - for attr in ("expr", "lvalue", "test", "handler"):
1.52 - value = getattr(node, attr, None)
1.53 - if value is not None:
1.54 - setattr(node, attr, self.dispatch(value))
1.55 - for attr in ("body", "else_", "finally_", "code"):
1.56 - value = getattr(node, attr, None)
1.57 - if value is not None:
1.58 - setattr(node, attr, self.dispatches(value))
1.59 - return node
1.60 + raise AnnotationMessage, "Node '%s' not supported." % node
1.61
1.62 def dispatch(self, node, *args):
1.63 try:
1.64 @@ -235,6 +225,10 @@
1.65
1.66 # Program structure/control-flow.
1.67
1.68 + def visitAssign(self, assign):
1.69 + assign.code = self.dispatches(assign.code)
1.70 + return assign
1.71 +
1.72 def visitConditional(self, conditional):
1.73
1.74 # Conditionals keep local namespace changes isolated.
1.75 @@ -260,6 +254,24 @@
1.76
1.77 return conditional
1.78
1.79 + def visitModule(self, module):
1.80 + module.code = self.dispatches(module.code)
1.81 + return module
1.82 +
1.83 + def visitPass(self, pass_):
1.84 + return pass_
1.85 +
1.86 + def visitSubprogram(self, subprogram):
1.87 + subprogram.code = self.dispatches(subprogram.code)
1.88 + return subprogram
1.89 +
1.90 + def visitTry(self, try_):
1.91 + try_.body = self.dispatches(try_.body)
1.92 + try_.handler = self.dispatches(try_.handler)
1.93 + try_.else_ = self.dispatches(try_.else_)
1.94 + try_.finally_ = self.dispatches(try_.finally_)
1.95 + return try_
1.96 +
1.97 # Namespace operations.
1.98
1.99 def visitLoadAttr(self, loadattr):
1.100 @@ -290,6 +302,11 @@
1.101 self.annotate(loadattr)
1.102 return loadattr
1.103
1.104 + def visitLoadExc(self, loadexc):
1.105 + self.namespace.types = self.namespace.raises[:]
1.106 + self.annotate(loadexc)
1.107 + return loadexc
1.108 +
1.109 def visitLoadName(self, loadname):
1.110 self.namespace.set_types(self.namespace.load(loadname.name))
1.111 result = loadname
1.112 @@ -313,8 +330,13 @@
1.113 self.annotate(loadtemp)
1.114 return loadtemp
1.115
1.116 + def visitNot(self, not_):
1.117 + not_.expr = self.dispatch(not_.expr)
1.118 + return not_
1.119 +
1.120 def visitRaise(self, raise_):
1.121 - raise_.traceback = self.dispatch(raise_.traceback)
1.122 + if getattr(raise_, "traceback", None) is not None:
1.123 + raise_.traceback = self.dispatch(raise_.traceback)
1.124 raise_.expr = self.dispatch(raise_.expr)
1.125
1.126 # Handle bare name exceptions by converting any classes to instances.
1.127 @@ -798,6 +820,7 @@
1.128 def merge_namespace(self, namespace):
1.129 self.merge_items(namespace.names.items())
1.130 combine(self.returns, namespace.returns)
1.131 + combine(self.raises, namespace.raises)
1.132 self.temp = namespace.temp
1.133
1.134 def merge_items(self, items):