# HG changeset patch # User paulb@jeremy # Date 1156114512 -7200 # Node ID 5c21b2a7220a03802dcc54d1d853c9b0c9e9f7b7 # Parent 4bd63abbd18878e3b39c015e49fb4bdcdf4ae1b1 Attempted to fix attribute access contexts and to provide some support for instantiation. diff -r 4bd63abbd188 -r 5c21b2a7220a annotate.py --- a/annotate.py Mon Aug 21 00:54:44 2006 +0200 +++ b/annotate.py Mon Aug 21 00:55:12 2006 +0200 @@ -369,22 +369,42 @@ # Inspect each attribute and extract the subprogram. for attribute, accessor in attributes: - if attribute is None: - print "Invocation type is None" - continue - - subprogram = attribute.type - - # If a subprogram is defined, invoke it. - - self.invoke_subprogram(invoke, subprogram) - invocations[callable] = subprogram # If a class is involved, presume that it must create a new # object. if isinstance(attr.type, Class): - self.namespace.set_types([Attribute(None, attribute.context)]) + + # Instantiate the class. + # NOTE: Should probably only allocate a single instance. + + instance = Instance() + instance.namespace = Namespace() + instance.namespace.store("__class__", [attr.type]) + instance = Attribute(None, instance) + + # For instantiations, switch the context. + + if attribute is not None: + attribute = Attribute(instance, attribute.type) + + # Skip cases where no callable is found. + + if attribute is not None: + + # If a subprogram is defined, invoke it. + + self.invoke_subprogram(invoke, attribute) + invocations[callable] = attribute.type + + else: + print "Invocation type is None" + + if isinstance(attr.type, Class): + + # Associate the instance with the result of this invocation. + + self.namespace.set_types([instance]) self.annotate(invoke) invoke.invocations = invocations @@ -413,7 +433,7 @@ context = None target = subprogram - print target + print subprogram, "->", context, target # Provide the correct namespace for the invocation. @@ -426,11 +446,11 @@ # Process the subprogram. - self.process_node(subprogram, namespace) + self.process_node(target, namespace) # NOTE: Improve and verify this. - if getattr(subprogram, "returns_value", 0): + if getattr(target, "returns_value", 0): self.namespace.set_types(self.last_returns) self.annotate(invoke) @@ -450,7 +470,7 @@ """ if context is not None: - args = [context] + invocation.args + args = [Self(context)] + invocation.args else: args = invocation.args @@ -590,6 +610,10 @@ def __repr__(self): return "Attribute of type %s (context %s)" % (self.type, self.context) +class Self: + def __init__(self, attribute): + self.types = [attribute] + def find_attributes(structure, name): """ @@ -664,6 +688,12 @@ if isinstance(structure, Attribute): structure = structure.type - return find_attributes(structure, name) + results = [] + for attribute, accessor in find_attributes(structure, name): + if attribute is not None and isinstance(structure, Structure): + results.append((Attribute(structure, attribute.type), accessor)) + else: + results.append((attribute, accessor)) + return results # vim: tabstop=4 expandtab shiftwidth=4 diff -r 4bd63abbd188 -r 5c21b2a7220a simplified.py --- a/simplified.py Mon Aug 21 00:54:44 2006 +0200 +++ b/simplified.py Mon Aug 21 00:55:12 2006 +0200 @@ -211,13 +211,14 @@ "A Python class." + pass + class Instance(Structure): "An instance." def __init__(self, **kw): Structure.__init__(self, **kw) - self.types = [self] class Constant(Instance):