# HG changeset patch # User paulb@jeremy # Date 1154268957 -7200 # Node ID f60941bcfca112bcfd900793e4da1cadc2c871c8 # Parent ace370706a11ef83bdb605caf7388bd444e68380 Added elementary built-in namespace support. Added a find_methods function for the traversal of class hierarchies. diff -r ace370706a11 -r f60941bcfca1 annotate.py --- a/annotate.py Sun Jul 30 02:00:33 2006 +0200 +++ b/annotate.py Sun Jul 30 16:15:57 2006 +0200 @@ -93,6 +93,28 @@ def __eq__(self, other): return hasattr(other, "type") and other.type == self.type or other == self.type +def find_methods(structure, name): + + """ + Find for the given 'structure' all methods for the given 'name', visiting + base classes where appropriate and returning the methods in order of + descending precedence for all possible base classes. + """ + + try: + return structure.namespace.load(name) + except KeyError: + methods = [] + if hasattr(structure, "base_refs"): + for base_refs in structure.base_refs: + for base_ref in base_refs: + l = find_methods(base_ref, name) + if l: + for method in l: + if method not in methods: + methods.append(method) + return methods + # Annotation. class Annotator(Visitor): @@ -115,12 +137,13 @@ self.visitor = self - def process(self, node, locals=None, globals=None): + def process(self, node, locals=None, globals=None, builtins=None): """ - Process a subprogram or module 'node', indicating any initial 'locals' - and 'globals' if either are defined. Return an annotated subprogram or - module. Note that this method may mutate nodes in the original program. + Process a subprogram or module 'node', indicating any initial 'locals', + 'globals' and 'builtins' if any are defined. Return an annotated + subprogram or module. Note that this method may mutate nodes in the + original program. """ # Obtain a namespace either based on locals or on a structure. @@ -132,6 +155,7 @@ # Determine the global namespace. self.global_namespace = globals or self.namespace # NOTE: Improve this. + self.builtins_namespace = builtins or self.namespace # NOTE: Improve this. node.namespace = self.namespace # Remember return values. @@ -203,7 +227,10 @@ return storename def visitLoadGlobal(self, loadglobal): - self.types = self.global_namespace.load(loadglobal.name) + try: + self.types = self.global_namespace.load(loadglobal.name) + except KeyError: + self.types = self.builtins_namespace.load(loadglobal.name) self.annotate(loadglobal) return loadglobal diff -r ace370706a11 -r f60941bcfca1 test.py --- a/test.py Sun Jul 30 02:00:33 2006 +0200 +++ b/test.py Sun Jul 30 16:15:57 2006 +0200 @@ -1,11 +1,17 @@ -import simplify, compiler, sys +import simplify, compiler, sys, os import fixnames import annotate -v = simplify.Simplifier() -f = fixnames.Fixer() a = annotate.Annotator() +b = compiler.parseFile(os.path.join("lib", "builtins.py")) m = compiler.parseFile(sys.argv[1]) -v.process(m) -f.process_all(v) -r = v.result +builtins_simplifier = simplify.Simplifier() +builtins_simplifier.process(b) +module_simplifier = simplify.Simplifier() +module_simplifier.process(m) +builtins_fixer = fixnames.Fixer() +builtins_fixer.process_all(builtins_simplifier) +module_fixer = fixnames.Fixer() +module_fixer.process_all(module_simplifier) +rb = builtins_simplifier.result +r = module_simplifier.result