# HG changeset patch # User paulb@jeremy # Date 1155490272 -7200 # Node ID 5603104f1d0db6263eece1675331b1069fb0d2b4 # Parent 222d7bf69b637f5c10a88e921a0c38039fcdd221 Rearranged definitions. diff -r 222d7bf69b63 -r 5603104f1d0d annotate.py --- a/annotate.py Sun Aug 13 18:57:43 2006 +0200 +++ b/annotate.py Sun Aug 13 19:31:12 2006 +0200 @@ -45,139 +45,6 @@ system = System() -# Namespace-related abstractions. - -class Namespace: - - """ - A local namespace which may either relate to a genuine set of function - locals or the initialisation of a structure. - """ - - def __init__(self): - self.names = {} - - def store(self, name, types): - self.names[name] = types - - def load(self, name): - return self.names[name] - - def merge(self, name, types): - if not self.names.has_key(name): - self.names[name] = types[:] - else: - existing = self.names[name] - for type in types: - if type not in existing: - existing.append(type) - - def merge_namespace(self, namespace): - self.merge_items(namespace.names.items()) - - def merge_items(self, items): - for name, types in items: - self.merge(name, types) - - def __repr__(self): - return repr(self.names) - -class Attribute: - - """ - An attribute abstraction, indicating the type of the attribute along with - its context or origin. - """ - - def __init__(self, context, type): - self.context = context - self.type = type - - def __eq__(self, other): - return hasattr(other, "type") and other.type == self.type or other == self.type - - def __repr__(self): - return "Attribute of type %s (context %s)" % (self.type, self.context) - -def find_attributes(structure, name): - - """ - Find for the given 'structure' all attributes for the given 'name', visiting - base classes where appropriate and returning the attributes in order of - descending precedence for all possible base classes. - - The elements in the result list are 2-tuples which contain the attribute and - the structure involved in accessing the attribute. - """ - - # First attempt to search the instance/class namespace. - - try: - l = structure.namespace.load(name) - attributes = [] - for attribute in l: - attributes.append((attribute, structure)) - - # If that does not work, attempt to investigate any class or base classes. - - except KeyError: - attributes = [] - - # Investigate any instance's implementing class. - - if isinstance(structure, Instance): - for cls in structure.namespace.load("__class__"): - l = find_attributes(cls, name) - for attribute in l: - if attribute not in attributes: - attributes.append(attribute) - - # Investigate any class's base classes. - - elif isinstance(structure, Class): - - # If no base classes exist, return an indicator that no attribute - # exists. - - if not structure.base_refs: - return [(None, structure)] - - # Otherwise, find all possible base classes. - - for base_refs in structure.base_refs: - base_attributes = [] - - # For each base class, find attributes either in the base - # class or its own base classes. - - for base_ref in base_refs: - l = find_attributes(base_ref, name) - for attribute in l: - if attribute not in base_attributes: - base_attributes.append(attribute) - - attributes += base_attributes - - return attributes - -def get_attributes(structure, name): - - """ - Return all possible attributes for the given 'structure' having the given - 'name', wrapping each attribute in an Attribute object which includes - context information for the attribute access. - - The elements in the result list are 2-tuples which contain the attribute and - the structure involved in accessing the attribute. - """ - - if isinstance(structure, Attribute): - structure = structure.type - attributes = find_attributes(structure, name) - for i, (attribute, accessor) in enumerate(attributes): - attributes[i] = Attribute(structure, attribute), accessor - return attributes - # Annotation. class Annotator(Visitor): @@ -658,4 +525,137 @@ namespace.merge_items(items) return namespace +# Namespace-related abstractions. + +class Namespace: + + """ + A local namespace which may either relate to a genuine set of function + locals or the initialisation of a structure. + """ + + def __init__(self): + self.names = {} + + def store(self, name, types): + self.names[name] = types + + def load(self, name): + return self.names[name] + + def merge(self, name, types): + if not self.names.has_key(name): + self.names[name] = types[:] + else: + existing = self.names[name] + for type in types: + if type not in existing: + existing.append(type) + + def merge_namespace(self, namespace): + self.merge_items(namespace.names.items()) + + def merge_items(self, items): + for name, types in items: + self.merge(name, types) + + def __repr__(self): + return repr(self.names) + +class Attribute: + + """ + An attribute abstraction, indicating the type of the attribute along with + its context or origin. + """ + + def __init__(self, context, type): + self.context = context + self.type = type + + def __eq__(self, other): + return hasattr(other, "type") and other.type == self.type or other == self.type + + def __repr__(self): + return "Attribute of type %s (context %s)" % (self.type, self.context) + +def find_attributes(structure, name): + + """ + Find for the given 'structure' all attributes for the given 'name', visiting + base classes where appropriate and returning the attributes in order of + descending precedence for all possible base classes. + + The elements in the result list are 2-tuples which contain the attribute and + the structure involved in accessing the attribute. + """ + + # First attempt to search the instance/class namespace. + + try: + l = structure.namespace.load(name) + attributes = [] + for attribute in l: + attributes.append((attribute, structure)) + + # If that does not work, attempt to investigate any class or base classes. + + except KeyError: + attributes = [] + + # Investigate any instance's implementing class. + + if isinstance(structure, Instance): + for cls in structure.namespace.load("__class__"): + l = find_attributes(cls, name) + for attribute in l: + if attribute not in attributes: + attributes.append(attribute) + + # Investigate any class's base classes. + + elif isinstance(structure, Class): + + # If no base classes exist, return an indicator that no attribute + # exists. + + if not structure.base_refs: + return [(None, structure)] + + # Otherwise, find all possible base classes. + + for base_refs in structure.base_refs: + base_attributes = [] + + # For each base class, find attributes either in the base + # class or its own base classes. + + for base_ref in base_refs: + l = find_attributes(base_ref, name) + for attribute in l: + if attribute not in base_attributes: + base_attributes.append(attribute) + + attributes += base_attributes + + return attributes + +def get_attributes(structure, name): + + """ + Return all possible attributes for the given 'structure' having the given + 'name', wrapping each attribute in an Attribute object which includes + context information for the attribute access. + + The elements in the result list are 2-tuples which contain the attribute and + the structure involved in accessing the attribute. + """ + + if isinstance(structure, Attribute): + structure = structure.type + attributes = find_attributes(structure, name) + for i, (attribute, accessor) in enumerate(attributes): + attributes[i] = Attribute(structure, attribute), accessor + return attributes + # vim: tabstop=4 expandtab shiftwidth=4