simplify

Changeset

121:01b51f1f7450
2006-10-30 paulb raw files shortlog changelog graph Fixed namespace replacement for module-level/global namespaces, ensuring that Conditional nodes replace the global namespace correctly. Added a non_types annotation for LoadAttr nodes. Reset the raised exceptions for else clauses in try...except...else statements. When merging namespaces, the temporary variables dictionary is copied, not acquired.
annotate.py (file)
     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: