diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2007-03-06 06:13:14 +0000 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2007-03-06 06:13:14 +0000 |
commit | 483a478ba8f2365258f23f196792c78e3dbd8375 (patch) | |
tree | 6304e97852550c1b0ca6068366a4373c95758b92 /lib/mako/ast.py | |
parent | 47afe17a7bf2f3a69e21ca326c0ee7db67c977be (diff) | |
download | external_python_mako-483a478ba8f2365258f23f196792c78e3dbd8375.tar.gz external_python_mako-483a478ba8f2365258f23f196792c78e3dbd8375.tar.bz2 external_python_mako-483a478ba8f2365258f23f196792c78e3dbd8375.zip |
further fix to previous ast enhancement; dont log identifiers as "declared" once we're traversing inside functions since they are local to the function.
Diffstat (limited to 'lib/mako/ast.py')
-rw-r--r-- | lib/mako/ast.py | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/lib/mako/ast.py b/lib/mako/ast.py index db281c8..129a726 100644 --- a/lib/mako/ast.py +++ b/lib/mako/ast.py @@ -40,54 +40,63 @@ class PythonCode(object): else: expr = code - local_ident_stack = {} class FindIdentifiers(object): - def visitAssName(s, node, *args): -# if node.name not in self.undeclared_identifiers: - self.declared_identifiers.add(node.name) - def visitAssign(s, node, *args): + def __init__(self): + self.in_function = False + self.local_ident_stack = {} + def _add_declared(s, name): + if not s.in_function: + self.declared_identifiers.add(name) + def visitAssName(self, node, *args): + self._add_declared(node.name) + def visitAssign(self, node, *args): # flip around the visiting of Assign so the expression gets evaluated first, # in the case of a clause like "x=x+5" (x is undeclared) - s.visit(node.expr, *args) + self.visit(node.expr, *args) for n in node.nodes: - s.visit(n, *args) - def visitFunction(s,node, *args): - # just need the function name. the contents of it are local to the function, dont parse those. - # TODO: parse the default values in the functions keyword arguments. - self.declared_identifiers.add(node.name) + self.visit(n, *args) + def visitFunction(self,node, *args): + self._add_declared(node.name) + # push function state onto stack. dont log any + # more identifiers as "declared" until outside of the function, + # but keep logging identifiers as "undeclared". + # track argument names in each function header so they arent counted as "undeclared" saved = {} + inf = self.in_function + self.in_function = True for arg in node.argnames: - if arg in local_ident_stack: + if arg in self.local_ident_stack: saved[arg] = True else: - local_ident_stack[arg] = True + self.local_ident_stack[arg] = True for n in node.getChildNodes(): - s.visit(n, *args) + self.visit(n, *args) + self.in_function = inf for arg in node.argnames: if arg not in saved: - del local_ident_stack[arg] - def visitFor(s, node, *args): + del self.local_ident_stack[arg] + def visitFor(self, node, *args): # flip around visit - s.visit(node.list, *args) - s.visit(node.assign, *args) - s.visit(node.body, *args) + self.visit(node.list, *args) + self.visit(node.assign, *args) + self.visit(node.body, *args) def visitName(s, node, *args): - if node.name not in __builtins__ and node.name not in self.declared_identifiers and node.name not in local_ident_stack: + if node.name not in __builtins__ and node.name not in self.declared_identifiers and node.name not in s.local_ident_stack: self.undeclared_identifiers.add(node.name) - def visitImport(s, node, *args): + def visitImport(self, node, *args): for (mod, alias) in node.names: if alias is not None: - self.declared_identifiers.add(alias) + self._add_declared(alias) else: - self.declared_identifiers.add(mod) - def visitFrom(s, node, *args): + self._add_declared(mod) + def visitFrom(self, node, *args): for (mod, alias) in node.names: if alias is not None: - self.declared_identifiers.add(alias) + self._add_declared(alias) else: if mod == '*': raise exceptions.CompileException("'import *' is not supported, since all identifier names must be explicitly declared. Please use the form 'from <modulename> import <name1>, <name2>, ...' instead.", lineno, pos, filename) - self.declared_identifiers.add(mod) + self._add_declared(mod) f = FindIdentifiers() visitor.walk(expr, f) #, walker=walker()) |