# HG changeset patch # User paulb@localhost.localdomain # Date 1165103406 -3600 # Node ID 045bd526bc79121f55c75db97525ef1f7f3a2df8 # Parent 8dd0a818223097c32dbb9f5db8acbfec9f806856 Added parameter types to the annotation book-keeping. Moved the annotation count test further into the invocation process, suppressing re-evaluation of default values. Made function namespaces include all known types for each parameter, not just the current invocation's supplied types. diff -r 8dd0a8182230 -r 045bd526bc79 annotate.py --- a/annotate.py Sun Dec 03 00:47:35 2006 +0100 +++ b/annotate.py Sun Dec 03 00:50:06 2006 +0100 @@ -55,14 +55,19 @@ def __init__(self): self.count = 0 + def init(self, node): if not hasattr(node, "types"): node.types = [] + def annotate(self, node, types): self.init(node) + self.combine(node.types, types) + + def combine(self, target, types): for type in types: - if type not in node.types: - node.types.append(type) + if type not in target: + target.append(type) self.count += 1 system = System() @@ -202,6 +207,21 @@ self.system.annotate(node, types or self.namespace.types) + def annotate_parameters(self, node, items): + + """ + Annotate the given 'node' using the given 'items' and updating the + system's annotation counter. + """ + + if not hasattr(node, "paramtypes"): + node.paramtypes = {} + + for param, types in items: + if not node.paramtypes.has_key(param): + node.paramtypes[param] = [] + self.system.combine(node.paramtypes[param], types) + # Visitor methods. def default(self, node): @@ -660,16 +680,6 @@ "Invoke using the given 'invoke' node the given 'subprogram'." - # Test to see if anything has changed. - - if hasattr(invoke, "syscount") and invoke.syscount == self.system.count: - return - - # Remember the state of the system. - - else: - invoke.syscount = self.system.count - # Test for context information, making it into a real attribute. if subprogram.context is not None: @@ -693,6 +703,16 @@ namespace = self.make_namespace(items) using_module_namespace = 0 + # Test to see if anything has changed. + + if hasattr(invoke, "syscount") and invoke.syscount == self.system.count: + return + + # Remember the state of the system. + + else: + invoke.syscount = self.system.count + # Process the subprogram. # In order to keep global accesses working, the module namespace must be # adjusted. @@ -855,7 +875,8 @@ raise AnnotationMessage, "Invocation provides unwanted *args." elif subprogram.star is not None: param, default = subprogram.star - arg = self.dispatch(default) # NOTE: Review reprocessing. + if not hasattr(arg, "types"): + arg = self.dispatch(default) # NOTE: Review reprocessing. items.append((param, arg.types)) if dstar_types is not None: @@ -866,20 +887,14 @@ raise AnnotationMessage, "Invocation provides unwanted **args." elif subprogram.dstar is not None: param, default = subprogram.dstar - arg = self.dispatch(default) # NOTE: Review reprocessing. + if not hasattr(arg, "types"): + arg = self.dispatch(default) # NOTE: Review reprocessing. items.append((param, arg.types)) # Record the parameter types. - if not hasattr(subprogram, "paramtypes"): - subprogram.paramtypes = {} - - for param, types in items: - if not subprogram.paramtypes.has_key(param): - subprogram.paramtypes[param] = [] - combine(subprogram.paramtypes[param], types) - - return items + self.annotate_parameters(subprogram, items) + return subprogram.paramtypes.items() def make_star_args(self, invocation, subprogram, star_args):