1.1 --- a/annotate.py Sat Oct 28 00:20:33 2006 +0200
1.2 +++ b/annotate.py Sat Oct 28 00:22:32 2006 +0200
1.3 @@ -313,6 +313,28 @@
1.4 self.annotate(loadtemp)
1.5 return loadtemp
1.6
1.7 + def visitRaise(self, raise_):
1.8 + raise_.traceback = self.dispatch(raise_.traceback)
1.9 + raise_.expr = self.dispatch(raise_.expr)
1.10 +
1.11 + # Handle bare name exceptions by converting any classes to instances.
1.12 +
1.13 + if not isinstance(raise_.expr, InvokeFunction):
1.14 + raise_.pos_args = []
1.15 + raise_.kw_args = {}
1.16 + raise_.star = None
1.17 + raise_.dstar = None
1.18 + types = []
1.19 + for attr in self.namespace.types:
1.20 + if isinstance(attr.type, Class):
1.21 + self._visitInvoke(raise_, [attr], have_args=0)
1.22 + types += self.namespace.types
1.23 + else:
1.24 + types = self.namespace.types
1.25 +
1.26 + combine(self.namespace.raises, types)
1.27 + return raise_
1.28 +
1.29 def visitReleaseTemp(self, releasetemp):
1.30 index = getattr(releasetemp, "index", None)
1.31 try:
1.32 @@ -360,7 +382,15 @@
1.33
1.34 # Invocations are a chapter of their own.
1.35
1.36 - def visitInvoke(self, invoke):
1.37 + def visitInvokeBlock(self, invoke):
1.38 +
1.39 + # First find the callables.
1.40 +
1.41 + invoke.expr = self.dispatch(invoke.expr)
1.42 + invocation_types = self.namespace.types
1.43 + return self._visitInvoke(invoke, invocation_types, have_args=0)
1.44 +
1.45 + def visitInvokeFunction(self, invoke):
1.46
1.47 # First find the callables.
1.48
1.49 @@ -370,8 +400,9 @@
1.50 # Invocation processing starts with making sure that the arguments have
1.51 # been processed.
1.52
1.53 - if isinstance(invoke, InvokeFunction):
1.54 - self.process_args(invoke)
1.55 + return self._visitInvoke(invoke, invocation_types, have_args=self.process_args(invoke))
1.56 +
1.57 + def _visitInvoke(self, invoke, invocation_types, have_args):
1.58
1.59 # Now locate and invoke the subprogram. This can be complicated because
1.60 # the target may be a class or object, and there may be many different
1.61 @@ -435,14 +466,22 @@
1.62 elif not isinstance(attr.type, Class):
1.63 print "Invocation type is None for", accessor
1.64
1.65 - # Special case: initialisation.
1.66 + else:
1.67
1.68 - if isinstance(attr.type, Class):
1.69 + # Test to see if no arguments were supplied in cases where no
1.70 + # initialiser was found.
1.71 +
1.72 + if have_args:
1.73 + raise AnnotationMessage, "No initialiser found for '%s' with arguments." % attr.type
1.74
1.75 - # Associate the instance with the result of this invocation.
1.76 + # Special case: initialisation.
1.77 +
1.78 + if isinstance(attr.type, Class):
1.79
1.80 - self.namespace.set_types([Attribute(None, instance)])
1.81 - self.annotate(invoke)
1.82 + # Associate the instance with the result of this invocation.
1.83 +
1.84 + self.namespace.set_types([Attribute(None, instance)])
1.85 + self.annotate(invoke)
1.86
1.87 # Remember the invocations that were found, along with the return type
1.88 # information.
1.89 @@ -451,9 +490,6 @@
1.90 self.namespace.set_types(getattr(invoke, "types", []))
1.91 return invoke
1.92
1.93 - visitInvokeFunction = visitInvoke
1.94 - visitInvokeBlock = visitInvoke
1.95 -
1.96 # Utility methods.
1.97
1.98 def new_instance(self, node, reason, target, type):
1.99 @@ -505,9 +541,11 @@
1.100
1.101 # Provide the correct namespace for the invocation.
1.102
1.103 - if isinstance(invoke, InvokeBlock):
1.104 + if getattr(invoke, "share_locals", 0):
1.105 namespace = Namespace()
1.106 namespace.merge_namespace(self.namespace)
1.107 + elif getattr(target, "structure", None):
1.108 + namespace = Namespace()
1.109 else:
1.110 items = self.make_items(invoke, target, context)
1.111 namespace = self.make_namespace(items)
1.112 @@ -523,15 +561,18 @@
1.113 self.namespace.set_types(self.last_returns)
1.114 self.annotate(invoke)
1.115
1.116 - # Otherwise, if it is a normal block, merge the locals.
1.117 + # Otherwise, assuming it is a normal block, merge the locals.
1.118
1.119 - elif isinstance(invoke, InvokeBlock):
1.120 + elif getattr(invoke, "share_locals", 0):
1.121 for locals in self.returned_locals:
1.122 self.namespace.merge_namespace(locals)
1.123
1.124 def process_args(self, invocation):
1.125
1.126 - "Process the arguments associated with an 'invocation'."
1.127 + """
1.128 + Process the arguments associated with an 'invocation'. Return whether
1.129 + any arguments were processed.
1.130 + """
1.131
1.132 invocation.pos_args = self.dispatches(invocation.pos_args)
1.133 invocation.kw_args = self.dispatch_dict(invocation.kw_args)
1.134 @@ -548,6 +589,11 @@
1.135 default = self.dispatch(default)
1.136 invocation.dstar = param, default
1.137
1.138 + if invocation.pos_args or invocation.kw_args or invocation.star or invocation.dstar:
1.139 + return 1
1.140 + else:
1.141 + return 0
1.142 +
1.143 def make_items(self, invocation, subprogram, context):
1.144
1.145 """
1.146 @@ -732,6 +778,7 @@
1.147 self.names = {}
1.148 self.returns = []
1.149 self.return_locals = []
1.150 + self.raises = []
1.151 self.temp = {}
1.152 self.types = []
1.153