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
2.1 --- a/fixnames.py Sat Oct 28 00:20:33 2006 +0200
2.2 +++ b/fixnames.py Sat Oct 28 00:22:32 2006 +0200
2.3 @@ -129,7 +129,7 @@
2.4 # Internal subprograms are skipped here and processed specially via
2.5 # Invoke nodes.
2.6
2.7 - if not getattr(subprogram, "acquire_locals", 0):
2.8 + if not getattr(subprogram, "internal", 0):
2.9 self.subprograms.append(self.process_node(subprogram))
2.10
2.11 # Ultimately, we redefine the list of subprograms on the visitor.
3.1 --- a/simplified.py Sat Oct 28 00:20:33 2006 +0200
3.2 +++ b/simplified.py Sat Oct 28 00:22:32 2006 +0200
3.3 @@ -228,8 +228,8 @@
3.4 if hasattr(self, "dstar") and self.dstar:
3.5 name, default = self.dstar
3.6 self._pprint(indent + 2, "( ", "%s default %s" % (name, default), stream=stream)
3.7 - if getattr(self, "acquire_locals", 0):
3.8 - self._pprint(indent + 2, "( ", "acquiring locals", stream=stream)
3.9 + if getattr(self, "internal", 0):
3.10 + self._pprint(indent + 2, "( ", "internal", stream=stream)
3.11 if getattr(self, "structure", 0):
3.12 self._pprint(indent + 2, "( ", "structure '%s'" % self.structure.name, stream=stream)
3.13
3.14 @@ -309,9 +309,10 @@
3.15 "A function or method invocation."
3.16
3.17 def __init__(self, *args, **kw):
3.18 - Node.__init__(self, *args, **kw)
3.19 + Invoke.__init__(self, *args, **kw)
3.20 if hasattr(self, "args"):
3.21 self.set_args(self.args)
3.22 + self.share_locals = 0
3.23
3.24 def set_args(self, args):
3.25
3.26 @@ -332,7 +333,13 @@
3.27 else:
3.28 raise TypeError, "Positional argument appears after keyword arguments in '%s'." % self
3.29
3.30 -class InvokeBlock(Invoke): "A block or loop invocation."
3.31 +class InvokeBlock(Invoke):
3.32 +
3.33 + "A block or loop invocation."
3.34 +
3.35 + def __init__(self, *args, **kw):
3.36 + self.share_locals = 1
3.37 + Invoke.__init__(self, *args, **kw)
3.38
3.39 # Named nodes are those which can be referenced in some way.
3.40
4.1 --- a/simplify.py Sat Oct 28 00:20:33 2006 +0200
4.2 +++ b/simplify.py Sat Oct 28 00:22:32 2006 +0200
4.3 @@ -213,11 +213,20 @@
4.4 return result
4.5
4.6 def visitRaise(self, raise_):
4.7 - result = Raise(raise_, 1, expr=self.dispatch(raise_.expr1), traceback=None)
4.8 - if raise_.expr2 is not None:
4.9 - result.args = [self.dispatch(raise_.expr2)]
4.10 + result = Raise(raise_, 1)
4.11 + if raise_.expr2 is None:
4.12 + result.expr = self.dispatch(raise_.expr1)
4.13 + else:
4.14 + result.expr = InvokeFunction(
4.15 + expr=self.dispatch(raise_.expr1),
4.16 + args=[self.dispatch(raise_.expr2)],
4.17 + star=None,
4.18 + dstar=None
4.19 + )
4.20 if raise_.expr3 is not None:
4.21 result.traceback = self.dispatch(raise_.expr3)
4.22 + else:
4.23 + result.traceback = None
4.24 return result
4.25
4.26 def _visitBuiltin(self, builtin, name):
4.27 @@ -398,7 +407,7 @@
4.28 (else) -> ...
4.29 """
4.30
4.31 - subprogram = Subprogram(name=None, acquire_locals=1, returns_value=1, params=[], star=None, dstar=None)
4.32 + subprogram = Subprogram(name=None, internal=1, returns_value=1, params=[], star=None, dstar=None)
4.33 self.current_subprograms.append(subprogram)
4.34
4.35 # In the subprogram, make instructions which invoke a method on the
4.36 @@ -503,7 +512,7 @@
4.37 (else) -> ...
4.38 """
4.39
4.40 - subprogram = Subprogram(name=None, acquire_locals=1, returns_value=1, params=[], star=None, dstar=None)
4.41 + subprogram = Subprogram(name=None, internal=1, returns_value=1, params=[], star=None, dstar=None)
4.42 self.current_subprograms.append(subprogram)
4.43
4.44 # In the subprogram, make instructions which store each operand, test
4.45 @@ -563,7 +572,7 @@
4.46 (else) -> ...
4.47 """
4.48
4.49 - subprogram = Subprogram(name=None, acquire_locals=1, returns_value=1, params=[], star=None, dstar=None)
4.50 + subprogram = Subprogram(name=None, internal=1, returns_value=1, params=[], star=None, dstar=None)
4.51 self.current_subprograms.append(subprogram)
4.52
4.53 # In the subprogram, make instructions which store each operand, test
4.54 @@ -1030,6 +1039,7 @@
4.55 expr=LoadRef(ref=structure)
4.56 ),
4.57 InvokeBlock(
4.58 + share_locals=0,
4.59 expr=LoadRef(ref=subprogram)
4.60 )
4.61 ]
4.62 @@ -1106,7 +1116,7 @@
4.63 (dstar)
4.64 """
4.65
4.66 - subprogram = Subprogram(name=function.name, acquire_locals=0, returns_value=1, star=None, dstar=None)
4.67 + subprogram = Subprogram(name=function.name, internal=0, returns_value=1, star=None, dstar=None)
4.68 self.current_subprograms.append(subprogram)
4.69 subprogram.code = self.dispatch(function.code) + [Return()]
4.70 self.current_subprograms.pop()
4.71 @@ -1122,7 +1132,7 @@
4.72 # Make a subprogram for the function and record it outside the main
4.73 # tree.
4.74
4.75 - subprogram = Subprogram(name=None, acquire_locals=0, returns_value=1, star=None, dstar=None)
4.76 + subprogram = Subprogram(name=None, internal=0, returns_value=1, star=None, dstar=None)
4.77 self.current_subprograms.append(subprogram)
4.78 subprogram.code = [Return(expr=self.dispatch(lambda_.code))]
4.79 self.current_subprograms.pop()
4.80 @@ -1157,7 +1167,7 @@
4.81 (else) -> ...
4.82 """
4.83
4.84 - subprogram = Subprogram(name=None, acquire_locals=1, returns_value=0, params=[], star=None, dstar=None)
4.85 + subprogram = Subprogram(name=None, internal=1, returns_value=0, params=[], star=None, dstar=None)
4.86 self.current_subprograms.append(subprogram)
4.87
4.88 # Include a conditional statement in the subprogram.
4.89 @@ -1213,7 +1223,7 @@
4.90 (else) -> ...
4.91 """
4.92
4.93 - subprogram = Subprogram(name=None, acquire_locals=1, returns_value=0, params=[], star=None, dstar=None)
4.94 + subprogram = Subprogram(name=None, internal=1, returns_value=0, params=[], star=None, dstar=None)
4.95 self.current_subprograms.append(subprogram)
4.96
4.97 # Always return from conditional sections/subprograms.
4.98 @@ -1246,8 +1256,9 @@
4.99 # Inside the conditional, add a recursive invocation to the subprogram
4.100 # if the test condition was satisfied.
4.101
4.102 - continuation = InvokeBlock()
4.103 - continuation.expr = LoadRef(ref=subprogram)
4.104 + continuation = InvokeBlock(
4.105 + expr=LoadRef(ref=subprogram)
4.106 + )
4.107 try_except.body = [assign] + self.dispatch(for_.body) + [continuation]
4.108 subprogram.code = [try_except, Return()]
4.109