1.1 --- a/annotate.py Sun Oct 29 22:47:42 2006 +0100
1.2 +++ b/annotate.py Mon Oct 30 23:32:38 2006 +0100
1.3 @@ -124,6 +124,7 @@
1.4 self.current_subprograms = []
1.5 self.current_namespaces = []
1.6 self.namespace = None
1.7 + self.module = module
1.8
1.9 # Give constants their own namespace.
1.10
1.11 @@ -153,11 +154,11 @@
1.12 # Record the current subprogram and namespace.
1.13
1.14 self.current_subprograms.append(node)
1.15 - self.current_namespaces.append(self.namespace)
1.16
1.17 # Determine the namespace.
1.18
1.19 if locals is not None:
1.20 + self.current_namespaces.append(self.namespace)
1.21 self.namespace = locals
1.22 else:
1.23 self.namespace = self.global_namespace
1.24 @@ -190,7 +191,8 @@
1.25
1.26 # Restore the previous subprogram and namespace.
1.27
1.28 - self.namespace = self.current_namespaces.pop()
1.29 + if locals is not None:
1.30 + self.namespace = self.current_namespaces.pop()
1.31 self.current_subprograms.pop()
1.32
1.33 return result
1.34 @@ -238,18 +240,25 @@
1.35
1.36 conditional.test = self.dispatch(conditional.test)
1.37 saved_namespace = self.namespace
1.38 + is_global = self.namespace is self.global_namespace
1.39
1.40 self.namespace = Namespace()
1.41 + if is_global:
1.42 + self.module.namespace = self.global_namespace = self.namespace
1.43 self.namespace.merge_namespace(saved_namespace)
1.44 conditional.body = self.dispatches(conditional.body)
1.45 body_namespace = self.namespace
1.46
1.47 self.namespace = Namespace()
1.48 + if is_global:
1.49 + self.module.namespace = self.global_namespace = self.namespace
1.50 self.namespace.merge_namespace(saved_namespace)
1.51 conditional.else_ = self.dispatches(conditional.else_)
1.52 else_namespace = self.namespace
1.53
1.54 self.namespace = Namespace()
1.55 + if is_global:
1.56 + self.module.namespace = self.global_namespace = self.namespace
1.57 self.namespace.merge_namespace(body_namespace)
1.58 self.namespace.merge_namespace(else_namespace)
1.59
1.60 @@ -269,7 +278,14 @@
1.61 def visitTry(self, try_):
1.62 try_.body = self.dispatches(try_.body)
1.63 try_.handler = self.dispatches(try_.handler)
1.64 + raises = self.namespace.raises
1.65 +
1.66 + # Empty the raised exceptions for the else clause.
1.67 +
1.68 + self.namespace.raises = []
1.69 try_.else_ = self.dispatches(try_.else_)
1.70 + self.namespace.raises = raises
1.71 +
1.72 try_.finally_ = self.dispatches(try_.finally_)
1.73 return try_
1.74
1.75 @@ -278,12 +294,14 @@
1.76 def visitLoadAttr(self, loadattr):
1.77 loadattr.expr = self.dispatch(loadattr.expr)
1.78 types = []
1.79 + non_types = []
1.80 accesses = {}
1.81 - non_accesses = {}
1.82 for attr in self.namespace.types:
1.83 attributes = get_attributes(attr.type, loadattr.name)
1.84 if not attributes:
1.85 print "No attributes for", loadattr.name, "in", attr.type
1.86 + if not attr.type in non_types:
1.87 + non_types.append(attr)
1.88 for attribute, accessor in attributes:
1.89 if attribute is not None:
1.90 types.append(attribute)
1.91 @@ -293,13 +311,11 @@
1.92 accesses[attr.type].append((attribute, accessor))
1.93 else:
1.94 print "Empty attribute", loadattr.name, "via accessor", accessor
1.95 - if not non_accesses.has_key(attr.type):
1.96 - non_accesses[attr.type] = []
1.97 - if not (attribute, accessor) in non_accesses[attr.type]:
1.98 - non_accesses[attr.type].append((attribute, accessor))
1.99 + if not attr.type in non_types:
1.100 + non_types.append(attr)
1.101 self.namespace.set_types(types)
1.102 + loadattr.non_types = non_types
1.103 loadattr.accesses = accesses
1.104 - loadattr.non_accesses = non_accesses
1.105 self.annotate(loadattr)
1.106 return loadattr
1.107
1.108 @@ -831,7 +847,8 @@
1.109 self.merge_items(namespace.names.items())
1.110 combine(self.returns, namespace.returns)
1.111 combine(self.raises, namespace.raises)
1.112 - self.temp = namespace.temp
1.113 + self.temp = {}
1.114 + self.temp.update(namespace.temp)
1.115
1.116 def merge_items(self, items):
1.117 for name, types in items: