1.1 --- a/annotate.py Sun Dec 03 00:47:35 2006 +0100
1.2 +++ b/annotate.py Sun Dec 03 00:50:06 2006 +0100
1.3 @@ -55,14 +55,19 @@
1.4
1.5 def __init__(self):
1.6 self.count = 0
1.7 +
1.8 def init(self, node):
1.9 if not hasattr(node, "types"):
1.10 node.types = []
1.11 +
1.12 def annotate(self, node, types):
1.13 self.init(node)
1.14 + self.combine(node.types, types)
1.15 +
1.16 + def combine(self, target, types):
1.17 for type in types:
1.18 - if type not in node.types:
1.19 - node.types.append(type)
1.20 + if type not in target:
1.21 + target.append(type)
1.22 self.count += 1
1.23
1.24 system = System()
1.25 @@ -202,6 +207,21 @@
1.26
1.27 self.system.annotate(node, types or self.namespace.types)
1.28
1.29 + def annotate_parameters(self, node, items):
1.30 +
1.31 + """
1.32 + Annotate the given 'node' using the given 'items' and updating the
1.33 + system's annotation counter.
1.34 + """
1.35 +
1.36 + if not hasattr(node, "paramtypes"):
1.37 + node.paramtypes = {}
1.38 +
1.39 + for param, types in items:
1.40 + if not node.paramtypes.has_key(param):
1.41 + node.paramtypes[param] = []
1.42 + self.system.combine(node.paramtypes[param], types)
1.43 +
1.44 # Visitor methods.
1.45
1.46 def default(self, node):
1.47 @@ -660,16 +680,6 @@
1.48
1.49 "Invoke using the given 'invoke' node the given 'subprogram'."
1.50
1.51 - # Test to see if anything has changed.
1.52 -
1.53 - if hasattr(invoke, "syscount") and invoke.syscount == self.system.count:
1.54 - return
1.55 -
1.56 - # Remember the state of the system.
1.57 -
1.58 - else:
1.59 - invoke.syscount = self.system.count
1.60 -
1.61 # Test for context information, making it into a real attribute.
1.62
1.63 if subprogram.context is not None:
1.64 @@ -693,6 +703,16 @@
1.65 namespace = self.make_namespace(items)
1.66 using_module_namespace = 0
1.67
1.68 + # Test to see if anything has changed.
1.69 +
1.70 + if hasattr(invoke, "syscount") and invoke.syscount == self.system.count:
1.71 + return
1.72 +
1.73 + # Remember the state of the system.
1.74 +
1.75 + else:
1.76 + invoke.syscount = self.system.count
1.77 +
1.78 # Process the subprogram.
1.79 # In order to keep global accesses working, the module namespace must be
1.80 # adjusted.
1.81 @@ -855,7 +875,8 @@
1.82 raise AnnotationMessage, "Invocation provides unwanted *args."
1.83 elif subprogram.star is not None:
1.84 param, default = subprogram.star
1.85 - arg = self.dispatch(default) # NOTE: Review reprocessing.
1.86 + if not hasattr(arg, "types"):
1.87 + arg = self.dispatch(default) # NOTE: Review reprocessing.
1.88 items.append((param, arg.types))
1.89
1.90 if dstar_types is not None:
1.91 @@ -866,20 +887,14 @@
1.92 raise AnnotationMessage, "Invocation provides unwanted **args."
1.93 elif subprogram.dstar is not None:
1.94 param, default = subprogram.dstar
1.95 - arg = self.dispatch(default) # NOTE: Review reprocessing.
1.96 + if not hasattr(arg, "types"):
1.97 + arg = self.dispatch(default) # NOTE: Review reprocessing.
1.98 items.append((param, arg.types))
1.99
1.100 # Record the parameter types.
1.101
1.102 - if not hasattr(subprogram, "paramtypes"):
1.103 - subprogram.paramtypes = {}
1.104 -
1.105 - for param, types in items:
1.106 - if not subprogram.paramtypes.has_key(param):
1.107 - subprogram.paramtypes[param] = []
1.108 - combine(subprogram.paramtypes[param], types)
1.109 -
1.110 - return items
1.111 + self.annotate_parameters(subprogram, items)
1.112 + return subprogram.paramtypes.items()
1.113
1.114 def make_star_args(self, invocation, subprogram, star_args):
1.115