# HG changeset patch # User paulb@jeremy # Date 1162143857 -3600 # Node ID 47cfa96935f6baaf6b2a3438dbecf0ca82f658c6 # Parent bbdb66bcd7c555590e255ad46b86d02ee25fb116 Removed default node handling. Changed namespace/subprogram save/restore to work with Conditional nodes. diff -r bbdb66bcd7c5 -r 47cfa96935f6 annotate.py --- a/annotate.py Sun Oct 29 18:43:29 2006 +0100 +++ b/annotate.py Sun Oct 29 18:44:17 2006 +0100 @@ -123,6 +123,7 @@ self.subprograms = [] self.current_subprograms = [] self.current_namespaces = [] + self.namespace = None # Give constants their own namespace. @@ -149,6 +150,11 @@ mutate nodes in the original program. """ + # Record the current subprogram and namespace. + + self.current_subprograms.append(node) + self.current_namespaces.append(self.namespace) + # Determine the namespace. if locals is not None: @@ -156,11 +162,6 @@ else: self.namespace = self.global_namespace - # Record the current subprogram and namespace. - - self.current_subprograms.append(node) - self.current_namespaces.append(self.namespace) - # Add namespace details to any structure involved. if getattr(node, "structure", None) is not None: @@ -188,10 +189,7 @@ # Restore the previous subprogram and namespace. - self.current_namespaces.pop() - if self.current_namespaces: - self.namespace = self.current_namespaces[-1] - + self.namespace = self.current_namespaces.pop() self.current_subprograms.pop() return result @@ -214,15 +212,7 @@ handler. """ - for attr in ("expr", "lvalue", "test", "handler"): - value = getattr(node, attr, None) - if value is not None: - setattr(node, attr, self.dispatch(value)) - for attr in ("body", "else_", "finally_", "code"): - value = getattr(node, attr, None) - if value is not None: - setattr(node, attr, self.dispatches(value)) - return node + raise AnnotationMessage, "Node '%s' not supported." % node def dispatch(self, node, *args): try: @@ -235,6 +225,10 @@ # Program structure/control-flow. + def visitAssign(self, assign): + assign.code = self.dispatches(assign.code) + return assign + def visitConditional(self, conditional): # Conditionals keep local namespace changes isolated. @@ -260,6 +254,24 @@ return conditional + def visitModule(self, module): + module.code = self.dispatches(module.code) + return module + + def visitPass(self, pass_): + return pass_ + + def visitSubprogram(self, subprogram): + subprogram.code = self.dispatches(subprogram.code) + return subprogram + + def visitTry(self, try_): + try_.body = self.dispatches(try_.body) + try_.handler = self.dispatches(try_.handler) + try_.else_ = self.dispatches(try_.else_) + try_.finally_ = self.dispatches(try_.finally_) + return try_ + # Namespace operations. def visitLoadAttr(self, loadattr): @@ -290,6 +302,11 @@ self.annotate(loadattr) return loadattr + def visitLoadExc(self, loadexc): + self.namespace.types = self.namespace.raises[:] + self.annotate(loadexc) + return loadexc + def visitLoadName(self, loadname): self.namespace.set_types(self.namespace.load(loadname.name)) result = loadname @@ -313,8 +330,13 @@ self.annotate(loadtemp) return loadtemp + def visitNot(self, not_): + not_.expr = self.dispatch(not_.expr) + return not_ + def visitRaise(self, raise_): - raise_.traceback = self.dispatch(raise_.traceback) + if getattr(raise_, "traceback", None) is not None: + raise_.traceback = self.dispatch(raise_.traceback) raise_.expr = self.dispatch(raise_.expr) # Handle bare name exceptions by converting any classes to instances. @@ -798,6 +820,7 @@ def merge_namespace(self, namespace): self.merge_items(namespace.names.items()) combine(self.returns, namespace.returns) + combine(self.raises, namespace.raises) self.temp = namespace.temp def merge_items(self, items):