1.1 --- a/annotate.py Sat Oct 21 02:54:39 2006 +0200
1.2 +++ b/annotate.py Sat Oct 21 02:56:25 2006 +0200
1.3 @@ -340,6 +340,7 @@
1.4 self.namespace = Namespace()
1.5 self.namespace.merge_namespace(body_namespace)
1.6 self.namespace.merge_namespace(else_namespace)
1.7 +
1.8 return conditional
1.9
1.10 def visitReturn(self, return_):
1.11 @@ -454,9 +455,18 @@
1.12 node.instances = {}
1.13
1.14 if not node.instances.has_key((reason, target, type)):
1.15 - instance = Instance()
1.16 - instance.namespace = Namespace()
1.17 - instance.namespace.store("__class__", [Attribute(None, type)])
1.18 +
1.19 + # Insist on a single instance per type.
1.20 + # NOTE: Strategy-dependent instantiation.
1.21 +
1.22 + if len(type.instances) == 0:
1.23 + instance = Instance()
1.24 + instance.namespace = Namespace()
1.25 + instance.namespace.store("__class__", [Attribute(None, type)])
1.26 + type.instances.append(instance)
1.27 + else:
1.28 + instance = type.instances[0]
1.29 +
1.30 node.instances[(reason, target, type)] = instance
1.31
1.32 return node.instances[(reason, target, type)]
1.33 @@ -498,12 +508,15 @@
1.34 self.process_node(target, namespace)
1.35
1.36 # NOTE: Improve and verify this.
1.37 + # If the invocation returns a value, acquire the return types.
1.38
1.39 if getattr(target, "returns_value", 0):
1.40 self.namespace.set_types(self.last_returns)
1.41 self.annotate(invoke)
1.42
1.43 - if isinstance(invoke, InvokeBlock):
1.44 + # Otherwise, if it is a normal block, merge the locals.
1.45 +
1.46 + elif isinstance(invoke, InvokeBlock):
1.47 for locals in self.returned_locals:
1.48 self.namespace.merge_namespace(locals)
1.49
1.50 @@ -795,10 +808,19 @@
1.51 return "Attribute(%s, %s)" % (repr(self.context), repr(self.type))
1.52
1.53 class Self:
1.54 +
1.55 + "A node encapsulating object/context information in an argument list."
1.56 +
1.57 def __init__(self, attribute):
1.58 self.types = [attribute]
1.59
1.60 def combine(target, additions):
1.61 +
1.62 + """
1.63 + Merge into the 'target' sequence the given 'additions', preventing duplicate
1.64 + items.
1.65 + """
1.66 +
1.67 for addition in additions:
1.68 if addition not in target:
1.69 target.append(addition)
2.1 --- a/simplified.py Sat Oct 21 02:54:39 2006 +0200
2.2 +++ b/simplified.py Sat Oct 21 02:56:25 2006 +0200
2.3 @@ -335,13 +335,12 @@
2.4 def full_name(self):
2.5 return self._full_name
2.6
2.7 -class Module(Node, WithName):
2.8 +class Module(Node):
2.9
2.10 "A Python module."
2.11
2.12 - def __init__(self, *args, **kw):
2.13 - Node.__init__(self, *args, **kw)
2.14 - WithName.__init__(self)
2.15 + def full_name(self):
2.16 + return self.name
2.17
2.18 class Subprogram(Node, WithName):
2.19
2.20 @@ -362,17 +361,27 @@
2.21 def __init__(self, *args, **kw):
2.22 Structure.__init__(self, *args, **kw)
2.23 WithName.__init__(self)
2.24 + self.instances = []
2.25
2.26 class Instance(Structure):
2.27
2.28 "An instance."
2.29
2.30 def full_name(self):
2.31 + # NOTE: Wrap the result in a call to name(self, ...) where multiple
2.32 + # NOTE: instances per class can occur.
2.33 return self.namespace.load("__class__")[0].type.full_name()
2.34
2.35 def __repr__(self):
2.36 return "Instance of type '%s'" % self.full_name()
2.37
2.38 + def __eq__(self, other):
2.39 + # NOTE: Assuming that multiple instances of the same class are equal.
2.40 + return self.full_name() == other.full_name()
2.41 +
2.42 + def __hash__(self):
2.43 + return id(self)
2.44 +
2.45 class Constant(Instance):
2.46
2.47 "A constant initialised with a type name for future processing."