1ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh"""Module symbol-table generator""" 2ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 3ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom compiler import ast 4ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom compiler.consts import SC_LOCAL, SC_GLOBAL_IMPLICIT, SC_GLOBAL_EXPLICIT, \ 5ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh SC_FREE, SC_CELL, SC_UNKNOWN 6ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom compiler.misc import mangle 7ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport types 8ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 9ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 10ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport sys 11ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 12ffab958fd8d42ed7227d83007350e61555a1fa36Andrew HsiehMANGLE_LEN = 256 13ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 14ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass Scope: 15ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # XXX how much information do I need about each name? 16ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def __init__(self, name, module, klass=None): 17ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.name = name 18ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.module = module 19ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.defs = {} 20ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.uses = {} 21ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.globals = {} 22ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.params = {} 23ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.frees = {} 24ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.cells = {} 25ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.children = [] 26ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # nested is true if the class could contain free variables, 27ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # i.e. if it is nested within another function. 28ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.nested = None 29ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.generator = None 30ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.klass = None 31ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if klass is not None: 32ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for i in range(len(klass)): 33ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if klass[i] != '_': 34ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.klass = klass[i:] 35ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh break 36ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 37ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def __repr__(self): 38ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return "<%s: %s>" % (self.__class__.__name__, self.name) 39ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 40ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def mangle(self, name): 41ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if self.klass is None: 42ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return name 43ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return mangle(name, self.klass) 44ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 45ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def add_def(self, name): 46ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.defs[self.mangle(name)] = 1 47ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 48ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def add_use(self, name): 49ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.uses[self.mangle(name)] = 1 50ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 51ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def add_global(self, name): 52ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh name = self.mangle(name) 53ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if name in self.uses or name in self.defs: 54ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass # XXX warn about global following def/use 55ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if name in self.params: 56ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh raise SyntaxError, "%s in %s is global and parameter" % \ 57ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh (name, self.name) 58ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.globals[name] = 1 59ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.module.add_def(name) 60ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 61ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def add_param(self, name): 62ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh name = self.mangle(name) 63ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.defs[name] = 1 64ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.params[name] = 1 65ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 66ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def get_names(self): 67ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh d = {} 68ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh d.update(self.defs) 69ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh d.update(self.uses) 70ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh d.update(self.globals) 71ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return d.keys() 72ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 73ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def add_child(self, child): 74ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.children.append(child) 75ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 76ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def get_children(self): 77ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return self.children 78ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 79ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def DEBUG(self): 80ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print >> sys.stderr, self.name, self.nested and "nested" or "" 81ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print >> sys.stderr, "\tglobals: ", self.globals 82ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print >> sys.stderr, "\tcells: ", self.cells 83ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print >> sys.stderr, "\tdefs: ", self.defs 84ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print >> sys.stderr, "\tuses: ", self.uses 85ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print >> sys.stderr, "\tfrees:", self.frees 86ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 87ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def check_name(self, name): 88ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Return scope of name. 89ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 90ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh The scope of a name could be LOCAL, GLOBAL, FREE, or CELL. 91ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 92ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if name in self.globals: 93ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return SC_GLOBAL_EXPLICIT 94ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if name in self.cells: 95ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return SC_CELL 96ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if name in self.defs: 97ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return SC_LOCAL 98ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if self.nested and (name in self.frees or name in self.uses): 99ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return SC_FREE 100ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if self.nested: 101ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return SC_UNKNOWN 102ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 103ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return SC_GLOBAL_IMPLICIT 104ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 105ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def get_free_vars(self): 106ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if not self.nested: 107ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return () 108ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh free = {} 109ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh free.update(self.frees) 110ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for name in self.uses.keys(): 111ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if name not in self.defs and name not in self.globals: 112ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh free[name] = 1 113ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return free.keys() 114ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 115ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def handle_children(self): 116ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for child in self.children: 117ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh frees = child.get_free_vars() 118ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh globals = self.add_frees(frees) 119ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for name in globals: 120ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh child.force_global(name) 121ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 122ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def force_global(self, name): 123ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Force name to be global in scope. 124ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 125ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh Some child of the current node had a free reference to name. 126ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh When the child was processed, it was labelled a free 127ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh variable. Now that all its enclosing scope have been 128ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh processed, the name is known to be a global or builtin. So 129ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh walk back down the child chain and set the name to be global 130ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh rather than free. 131ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 132ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh Be careful to stop if a child does not think the name is 133ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh free. 134ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 135ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.globals[name] = 1 136ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if name in self.frees: 137ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh del self.frees[name] 138ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for child in self.children: 139ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if child.check_name(name) == SC_FREE: 140ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh child.force_global(name) 141ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 142ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def add_frees(self, names): 143ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Process list of free vars from nested scope. 144ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 145ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh Returns a list of names that are either 1) declared global in the 146ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh parent or 2) undefined in a top-level parent. In either case, 147ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh the nested scope should treat them as globals. 148ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 149ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh child_globals = [] 150ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for name in names: 151ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh sc = self.check_name(name) 152ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if self.nested: 153ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if sc == SC_UNKNOWN or sc == SC_FREE \ 154ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh or isinstance(self, ClassScope): 155ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.frees[name] = 1 156ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif sc == SC_GLOBAL_IMPLICIT: 157ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh child_globals.append(name) 158ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(self, FunctionScope) and sc == SC_LOCAL: 159ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.cells[name] = 1 160ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif sc != SC_CELL: 161ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh child_globals.append(name) 162ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 163ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if sc == SC_LOCAL: 164ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.cells[name] = 1 165ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif sc != SC_CELL: 166ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh child_globals.append(name) 167ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return child_globals 168ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 169ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def get_cell_vars(self): 170ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return self.cells.keys() 171ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 172ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass ModuleScope(Scope): 173ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh __super_init = Scope.__init__ 174ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 175ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def __init__(self): 176ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.__super_init("global", self) 177ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 178ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass FunctionScope(Scope): 179ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 180ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 181ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass GenExprScope(Scope): 182ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh __super_init = Scope.__init__ 183ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 184ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh __counter = 1 185ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 186ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def __init__(self, module, klass=None): 187ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh i = self.__counter 188ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.__counter += 1 189ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.__super_init("generator expression<%d>"%i, module, klass) 190ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.add_param('.0') 191ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 192ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def get_names(self): 193ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh keys = Scope.get_names(self) 194ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return keys 195ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 196ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass LambdaScope(FunctionScope): 197ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh __super_init = Scope.__init__ 198ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 199ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh __counter = 1 200ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 201ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def __init__(self, module, klass=None): 202ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh i = self.__counter 203ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.__counter += 1 204ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.__super_init("lambda.%d" % i, module, klass) 205ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 206ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass ClassScope(Scope): 207ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh __super_init = Scope.__init__ 208ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 209ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def __init__(self, name, module): 210ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.__super_init(name, module, name) 211ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 212ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass SymbolVisitor: 213ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def __init__(self): 214ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.scopes = {} 215ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.klass = None 216ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 217ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # node that define new scopes 218ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 219ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitModule(self, node): 220ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope = self.module = self.scopes[node] = ModuleScope() 221ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.node, scope) 222ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 223ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh visitExpression = visitModule 224ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 225ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitFunction(self, node, parent): 226ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if node.decorators: 227ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.decorators, parent) 228ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh parent.add_def(node.name) 229ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for n in node.defaults: 230ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(n, parent) 231ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope = FunctionScope(node.name, self.module, self.klass) 232ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if parent.nested or isinstance(parent, FunctionScope): 233ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.nested = 1 234ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.scopes[node] = scope 235ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self._do_args(scope, node.argnames) 236ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.code, scope) 237ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.handle_free_vars(scope, parent) 238ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 239ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitGenExpr(self, node, parent): 240ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope = GenExprScope(self.module, self.klass); 241ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if parent.nested or isinstance(parent, FunctionScope) \ 242ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh or isinstance(parent, GenExprScope): 243ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.nested = 1 244ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 245ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.scopes[node] = scope 246ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.code, scope) 247ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 248ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.handle_free_vars(scope, parent) 249ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 250ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitGenExprInner(self, node, scope): 251ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for genfor in node.quals: 252ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(genfor, scope) 253ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 254ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.expr, scope) 255ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 256ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitGenExprFor(self, node, scope): 257ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.assign, scope, 1) 258ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.iter, scope) 259ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for if_ in node.ifs: 260ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(if_, scope) 261ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 262ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitGenExprIf(self, node, scope): 263ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.test, scope) 264ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 265ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitLambda(self, node, parent, assign=0): 266ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Lambda is an expression, so it could appear in an expression 267ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # context where assign is passed. The transformer should catch 268ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # any code that has a lambda on the left-hand side. 269ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh assert not assign 270ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 271ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for n in node.defaults: 272ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(n, parent) 273ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope = LambdaScope(self.module, self.klass) 274ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if parent.nested or isinstance(parent, FunctionScope): 275ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.nested = 1 276ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.scopes[node] = scope 277ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self._do_args(scope, node.argnames) 278ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.code, scope) 279ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.handle_free_vars(scope, parent) 280ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 281ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def _do_args(self, scope, args): 282ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for name in args: 283ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if type(name) == types.TupleType: 284ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self._do_args(scope, name) 285ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 286ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.add_param(name) 287ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 288ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def handle_free_vars(self, scope, parent): 289ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh parent.add_child(scope) 290ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.handle_children() 291ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 292ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitClass(self, node, parent): 293ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh parent.add_def(node.name) 294ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for n in node.bases: 295ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(n, parent) 296ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope = ClassScope(node.name, self.module) 297ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if parent.nested or isinstance(parent, FunctionScope): 298ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.nested = 1 299ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if node.doc is not None: 300ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.add_def('__doc__') 301ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.add_def('__module__') 302ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.scopes[node] = scope 303ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh prev = self.klass 304ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.klass = node.name 305ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.code, scope) 306ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.klass = prev 307ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.handle_free_vars(scope, parent) 308ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 309ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # name can be a def or a use 310ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 311ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # XXX a few calls and nodes expect a third "assign" arg that is 312ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # true if the name is being used as an assignment. only 313ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # expressions contained within statements may have the assign arg. 314ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 315ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitName(self, node, scope, assign=0): 316ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if assign: 317ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.add_def(node.name) 318ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 319ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.add_use(node.name) 320ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 321ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # operations that bind new names 322ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 323ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitFor(self, node, scope): 324ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.assign, scope, 1) 325ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.list, scope) 326ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.body, scope) 327ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if node.else_: 328ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.else_, scope) 329ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 330ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitFrom(self, node, scope): 331ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for name, asname in node.names: 332ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if name == "*": 333ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh continue 334ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.add_def(asname or name) 335ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 336ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitImport(self, node, scope): 337ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for name, asname in node.names: 338ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh i = name.find(".") 339ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if i > -1: 340ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh name = name[:i] 341ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.add_def(asname or name) 342ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 343ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitGlobal(self, node, scope): 344ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for name in node.names: 345ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.add_global(name) 346ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 347ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitAssign(self, node, scope): 348ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Propagate assignment flag down to child nodes. 349ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 350ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh The Assign node doesn't itself contains the variables being 351ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh assigned to. Instead, the children in node.nodes are visited 352ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh with the assign flag set to true. When the names occur in 353ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh those nodes, they are marked as defs. 354ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 355ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh Some names that occur in an assignment target are not bound by 356ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh the assignment, e.g. a name occurring inside a slice. The 357ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh visitor handles these nodes specially; they do not propagate 358ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh the assign flag to their children. 359ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 360ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for n in node.nodes: 361ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(n, scope, 1) 362ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.expr, scope) 363ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 364ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitAssName(self, node, scope, assign=1): 365ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.add_def(node.name) 366ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 367ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitAssAttr(self, node, scope, assign=0): 368ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.expr, scope, 0) 369ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 370ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitSubscript(self, node, scope, assign=0): 371ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.expr, scope, 0) 372ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for n in node.subs: 373ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(n, scope, 0) 374ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 375ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitSlice(self, node, scope, assign=0): 376ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.expr, scope, 0) 377ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if node.lower: 378ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.lower, scope, 0) 379ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if node.upper: 380ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.upper, scope, 0) 381ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 382ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitAugAssign(self, node, scope): 383ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # If the LHS is a name, then this counts as assignment. 384ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Otherwise, it's just use. 385ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.node, scope) 386ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(node.node, ast.Name): 387ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.node, scope, 1) # XXX worry about this 388ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.expr, scope) 389ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 390ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # prune if statements if tests are false 391ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 392ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _const_types = types.StringType, types.IntType, types.FloatType 393ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 394ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitIf(self, node, scope): 395ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for test, body in node.tests: 396ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(test, ast.Const): 397ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if type(test.value) in self._const_types: 398ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if not test.value: 399ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh continue 400ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(test, scope) 401ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(body, scope) 402ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if node.else_: 403ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.else_, scope) 404ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 405ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # a yield statement signals a generator 406ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 407ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def visitYield(self, node, scope): 408ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scope.generator = 1 409ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.visit(node.value, scope) 410ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 411ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef list_eq(l1, l2): 412ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return sorted(l1) == sorted(l2) 413ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 414ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehif __name__ == "__main__": 415ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh import sys 416ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh from compiler import parseFile, walk 417ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh import symtable 418ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 419ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def get_names(syms): 420ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return [s for s in [s.get_name() for s in syms.get_symbols()] 421ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if not (s.startswith('_[') or s.startswith('.'))] 422ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 423ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for file in sys.argv[1:]: 424ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print file 425ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = open(file) 426ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh buf = f.read() 427ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 428ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh syms = symtable.symtable(buf, file, "exec") 429ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh mod_names = get_names(syms) 430ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh tree = parseFile(file) 431ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh s = SymbolVisitor() 432ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh walk(tree, s) 433ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 434ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # compare module-level symbols 435ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh names2 = s.scopes[tree].get_names() 436ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 437ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if not list_eq(mod_names, names2): 438ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print 439ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print "oops", file 440ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print sorted(mod_names) 441ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print sorted(names2) 442ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh sys.exit(-1) 443ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 444ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh d = {} 445ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh d.update(s.scopes) 446ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh del d[tree] 447ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh scopes = d.values() 448ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh del d 449ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 450ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for s in syms.get_symbols(): 451ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if s.is_namespace(): 452ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh l = [sc for sc in scopes 453ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if sc.name == s.get_name()] 454ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if len(l) > 1: 455ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print "skipping", s.get_name() 456ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 457ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if not list_eq(get_names(s.get_namespace()), 458ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh l[0].get_names()): 459ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print s.get_name() 460ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print sorted(get_names(s.get_namespace())) 461ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh print sorted(l[0].get_names()) 462ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh sys.exit(-1) 463