diff options
| author | NCH(OpenERP) <> | 2009-12-15 14:02:18 +0530 |
|---|---|---|
| committer | hda (Tiny) <hda@tinyerp.com> | 2009-12-15 14:02:18 +0530 |
| commit | 3bcfde0b35e95c4cebfca52d5777626fa09b7fe2 (patch) | |
| tree | 598dc3e05e1950f2704267c9ae5c9c8d6b00d471 /bin/mako/codegen.py | |
| parent | 3f33f865f59e7acd09b1b3e3d6b1e5a7c3b47076 (diff) | |
| parent | 99ffac43ea7e7a82adc720bd286321eac26fcdb3 (diff) | |
Removed mako from source and improved printscreen report
bzr revid: hda@tinyerp.com-20091215083218-4pcbwf7vcpi5e90y
Diffstat (limited to 'bin/mako/codegen.py')
| -rwxr-xr-x | bin/mako/codegen.py | 707 |
1 files changed, 0 insertions, 707 deletions
diff --git a/bin/mako/codegen.py b/bin/mako/codegen.py deleted file mode 100755 index ee01713bd2f..00000000000 --- a/bin/mako/codegen.py +++ /dev/null @@ -1,707 +0,0 @@ -# -*- coding: utf-8 -*- -# codegen.py -# Copyright (C) 2006, 2007, 2008 Michael Bayer mike_mp@zzzcomputing.com -# -# This module is part of Mako and is released under -# the MIT License: http://www.opensource.org/licenses/mit-license.php - -"""provides functionality for rendering a parsetree constructing into module source code.""" - -import time -import re -from mako.pygen import PythonPrinter -from mako import util, ast, parsetree, filters - -MAGIC_NUMBER = 5 - - -def compile(node, uri, filename=None, default_filters=None, buffer_filters=None, imports=None, source_encoding=None, generate_unicode=True): - """generate module source code given a parsetree node, uri, and optional source filename""" - - buf = util.FastEncodingBuffer(unicode=generate_unicode) - - printer = PythonPrinter(buf) - _GenerateRenderMethod(printer, _CompileContext(uri, filename, default_filters, buffer_filters, imports, source_encoding, generate_unicode), node) - return buf.getvalue() - -class _CompileContext(object): - def __init__(self, uri, filename, default_filters, buffer_filters, imports, source_encoding, generate_unicode): - self.uri = uri - self.filename = filename - self.default_filters = default_filters - self.buffer_filters = buffer_filters - self.imports = imports - self.source_encoding = source_encoding - self.generate_unicode = generate_unicode - -class _GenerateRenderMethod(object): - """a template visitor object which generates the full module source for a template.""" - def __init__(self, printer, compiler, node): - self.printer = printer - self.last_source_line = -1 - self.compiler = compiler - self.node = node - self.identifier_stack = [None] - - self.in_def = isinstance(node, parsetree.DefTag) - - if self.in_def: - name = "render_" + node.name - args = node.function_decl.get_argument_expressions() - filtered = len(node.filter_args.args) > 0 - buffered = eval(node.attributes.get('buffered', 'False')) - cached = eval(node.attributes.get('cached', 'False')) - defs = None - pagetag = None - else: - defs = self.write_toplevel() - pagetag = self.compiler.pagetag - name = "render_body" - if pagetag is not None: - args = pagetag.body_decl.get_argument_expressions() - if not pagetag.body_decl.kwargs: - args += ['**pageargs'] - cached = eval(pagetag.attributes.get('cached', 'False')) - else: - args = ['**pageargs'] - cached = False - buffered = filtered = False - if args is None: - args = ['context'] - else: - args = [a for a in ['context'] + args] - - self.write_render_callable(pagetag or node, name, args, buffered, filtered, cached) - - if defs is not None: - for node in defs: - _GenerateRenderMethod(printer, compiler, node) - - identifiers = property(lambda self:self.identifier_stack[-1]) - - def write_toplevel(self): - """traverse a template structure for module-level directives and generate the - start of module-level code.""" - inherit = [] - namespaces = {} - module_code = [] - encoding =[None] - - self.compiler.pagetag = None - - class FindTopLevel(object): - def visitInheritTag(s, node): - inherit.append(node) - def visitNamespaceTag(s, node): - namespaces[node.name] = node - def visitPageTag(s, node): - self.compiler.pagetag = node - def visitCode(s, node): - if node.ismodule: - module_code.append(node) - - f = FindTopLevel() - for n in self.node.nodes: - n.accept_visitor(f) - - self.compiler.namespaces = namespaces - - module_ident = util.Set() - for n in module_code: - module_ident = module_ident.union(n.declared_identifiers()) - - module_identifiers = _Identifiers() - module_identifiers.declared = module_ident - - # module-level names, python code - if not self.compiler.generate_unicode and self.compiler.source_encoding: - self.printer.writeline("# -*- encoding:%s -*-" % self.compiler.source_encoding) - - self.printer.writeline("from mako import runtime, filters, cache") - self.printer.writeline("UNDEFINED = runtime.UNDEFINED") - self.printer.writeline("__M_dict_builtin = dict") - self.printer.writeline("__M_locals_builtin = locals") - self.printer.writeline("_magic_number = %s" % repr(MAGIC_NUMBER)) - self.printer.writeline("_modified_time = %s" % repr(time.time())) - self.printer.writeline("_template_filename=%s" % repr(self.compiler.filename)) - self.printer.writeline("_template_uri=%s" % repr(self.compiler.uri)) - self.printer.writeline("_template_cache=cache.Cache(__name__, _modified_time)") - self.printer.writeline("_source_encoding=%s" % repr(self.compiler.source_encoding)) - if self.compiler.imports: - buf = '' - for imp in self.compiler.imports: - buf += imp + "\n" - self.printer.writeline(imp) - impcode = ast.PythonCode(buf, source='', lineno=0, pos=0, filename='template defined imports') - else: - impcode = None - - main_identifiers = module_identifiers.branch(self.node) - module_identifiers.topleveldefs = module_identifiers.topleveldefs.union(main_identifiers.topleveldefs) - [module_identifiers.declared.add(x) for x in ["UNDEFINED"]] - if impcode: - [module_identifiers.declared.add(x) for x in impcode.declared_identifiers] - - self.compiler.identifiers = module_identifiers - self.printer.writeline("_exports = %s" % repr([n.name for n in main_identifiers.topleveldefs.values()])) - self.printer.write("\n\n") - - if len(module_code): - self.write_module_code(module_code) - - if len(inherit): - self.write_namespaces(namespaces) - self.write_inherit(inherit[-1]) - elif len(namespaces): - self.write_namespaces(namespaces) - - return main_identifiers.topleveldefs.values() - - def write_render_callable(self, node, name, args, buffered, filtered, cached): - """write a top-level render callable. - - this could be the main render() method or that of a top-level def.""" - self.printer.writelines( - "def %s(%s):" % (name, ','.join(args)), - "context.caller_stack._push_frame()", - "try:" - ) - if buffered or filtered or cached: - self.printer.writeline("context._push_buffer()") - - self.identifier_stack.append(self.compiler.identifiers.branch(self.node)) - if not self.in_def and '**pageargs' in args: - self.identifier_stack[-1].argument_declared.add('pageargs') - - if not self.in_def and (len(self.identifiers.locally_assigned) > 0 or len(self.identifiers.argument_declared)>0): - self.printer.writeline("__M_locals = __M_dict_builtin(%s)" % ','.join(["%s=%s" % (x, x) for x in self.identifiers.argument_declared])) - - self.write_variable_declares(self.identifiers, toplevel=True) - - for n in self.node.nodes: - n.accept_visitor(self) - - self.write_def_finish(self.node, buffered, filtered, cached) - self.printer.writeline(None) - self.printer.write("\n\n") - if cached: - self.write_cache_decorator(node, name, args, buffered, self.identifiers, toplevel=True) - - def write_module_code(self, module_code): - """write module-level template code, i.e. that which is enclosed in <%! %> tags - in the template.""" - for n in module_code: - self.write_source_comment(n) - self.printer.write_indented_block(n.text) - - def write_inherit(self, node): - """write the module-level inheritance-determination callable.""" - self.printer.writelines( - "def _mako_inherit(template, context):", - "_mako_generate_namespaces(context)", - "return runtime._inherit_from(context, %s, _template_uri)" % (node.parsed_attributes['file']), - None - ) - - def write_namespaces(self, namespaces): - """write the module-level namespace-generating callable.""" - self.printer.writelines( - "def _mako_get_namespace(context, name):", - "try:", - "return context.namespaces[(__name__, name)]", - "except KeyError:", - "_mako_generate_namespaces(context)", - "return context.namespaces[(__name__, name)]", - None,None - ) - self.printer.writeline("def _mako_generate_namespaces(context):") - for node in namespaces.values(): - if node.attributes.has_key('import'): - self.compiler.has_ns_imports = True - self.write_source_comment(node) - if len(node.nodes): - self.printer.writeline("def make_namespace():") - export = [] - identifiers = self.compiler.identifiers.branch(node) - class NSDefVisitor(object): - def visitDefTag(s, node): - self.write_inline_def(node, identifiers, nested=False) - export.append(node.name) - vis = NSDefVisitor() - for n in node.nodes: - n.accept_visitor(vis) - self.printer.writeline("return [%s]" % (','.join(export))) - self.printer.writeline(None) - callable_name = "make_namespace()" - else: - callable_name = "None" - self.printer.writeline("ns = runtime.Namespace(%s, context._clean_inheritance_tokens(), templateuri=%s, callables=%s, calling_uri=_template_uri, module=%s)" % (repr(node.name), node.parsed_attributes.get('file', 'None'), callable_name, node.parsed_attributes.get('module', 'None'))) - if eval(node.attributes.get('inheritable', "False")): - self.printer.writeline("context['self'].%s = ns" % (node.name)) - self.printer.writeline("context.namespaces[(__name__, %s)] = ns" % repr(node.name)) - self.printer.write("\n") - if not len(namespaces): - self.printer.writeline("pass") - self.printer.writeline(None) - - def write_variable_declares(self, identifiers, toplevel=False, limit=None): - """write variable declarations at the top of a function. - - the variable declarations are in the form of callable definitions for defs and/or - name lookup within the function's context argument. the names declared are based on the - names that are referenced in the function body, which don't otherwise have any explicit - assignment operation. names that are assigned within the body are assumed to be - locally-scoped variables and are not separately declared. - - for def callable definitions, if the def is a top-level callable then a - 'stub' callable is generated which wraps the current Context into a closure. if the def - is not top-level, it is fully rendered as a local closure.""" - - # collection of all defs available to us in this scope - comp_idents = dict([(c.name, c) for c in identifiers.defs]) - to_write = util.Set() - - # write "context.get()" for all variables we are going to need that arent in the namespace yet - to_write = to_write.union(identifiers.undeclared) - - # write closure functions for closures that we define right here - to_write = to_write.union(util.Set([c.name for c in identifiers.closuredefs.values()])) - - # remove identifiers that are declared in the argument signature of the callable - to_write = to_write.difference(identifiers.argument_declared) - - # remove identifiers that we are going to assign to. in this way we mimic Python's behavior, - # i.e. assignment to a variable within a block means that variable is now a "locally declared" var, - # which cannot be referenced beforehand. - to_write = to_write.difference(identifiers.locally_declared) - - # if a limiting set was sent, constraint to those items in that list - # (this is used for the caching decorator) - if limit is not None: - to_write = to_write.intersection(limit) - - if toplevel and getattr(self.compiler, 'has_ns_imports', False): - self.printer.writeline("_import_ns = {}") - self.compiler.has_imports = True - for ident, ns in self.compiler.namespaces.iteritems(): - if ns.attributes.has_key('import'): - self.printer.writeline("_mako_get_namespace(context, %s)._populate(_import_ns, %s)" % (repr(ident), repr(re.split(r'\s*,\s*', ns.attributes['import'])))) - - for ident in to_write: - if ident in comp_idents: - comp = comp_idents[ident] - if comp.is_root(): - self.write_def_decl(comp, identifiers) - else: - self.write_inline_def(comp, identifiers, nested=True) - elif ident in self.compiler.namespaces: - self.printer.writeline("%s = _mako_get_namespace(context, %s)" % (ident, repr(ident))) - else: - if getattr(self.compiler, 'has_ns_imports', False): - self.printer.writeline("%s = _import_ns.get(%s, context.get(%s, UNDEFINED))" % (ident, repr(ident), repr(ident))) - else: - self.printer.writeline("%s = context.get(%s, UNDEFINED)" % (ident, repr(ident))) - - self.printer.writeline("__M_writer = context.writer()") - - def write_source_comment(self, node): - """write a source comment containing the line number of the corresponding template line.""" - if self.last_source_line != node.lineno: - self.printer.writeline("# SOURCE LINE %d" % node.lineno) - self.last_source_line = node.lineno - - def write_def_decl(self, node, identifiers): - """write a locally-available callable referencing a top-level def""" - funcname = node.function_decl.funcname - namedecls = node.function_decl.get_argument_expressions() - nameargs = node.function_decl.get_argument_expressions(include_defaults=False) - if not self.in_def and (len(self.identifiers.locally_assigned) > 0 or len(self.identifiers.argument_declared) > 0): - nameargs.insert(0, 'context.locals_(__M_locals)') - else: - nameargs.insert(0, 'context') - self.printer.writeline("def %s(%s):" % (funcname, ",".join(namedecls))) - self.printer.writeline("return render_%s(%s)" % (funcname, ",".join(nameargs))) - self.printer.writeline(None) - - def write_inline_def(self, node, identifiers, nested): - """write a locally-available def callable inside an enclosing def.""" - namedecls = node.function_decl.get_argument_expressions() - self.printer.writeline("def %s(%s):" % (node.name, ",".join(namedecls))) - filtered = len(node.filter_args.args) > 0 - buffered = eval(node.attributes.get('buffered', 'False')) - cached = eval(node.attributes.get('cached', 'False')) - self.printer.writelines( - "context.caller_stack._push_frame()", - "try:" - ) - if buffered or filtered or cached: - self.printer.writelines( - "context._push_buffer()", - ) - - identifiers = identifiers.branch(node, nested=nested) - - self.write_variable_declares(identifiers) - - self.identifier_stack.append(identifiers) - for n in node.nodes: - n.accept_visitor(self) - self.identifier_stack.pop() - - self.write_def_finish(node, buffered, filtered, cached) - self.printer.writeline(None) - if cached: - self.write_cache_decorator(node, node.name, namedecls, False, identifiers, inline=True, toplevel=False) - - def write_def_finish(self, node, buffered, filtered, cached, callstack=True): - """write the end section of a rendering function, either outermost or inline. - - this takes into account if the rendering function was filtered, buffered, etc. - and closes the corresponding try: block if any, and writes code to retrieve captured content, - apply filters, send proper return value.""" - if not buffered and not cached and not filtered: - self.printer.writeline("return ''") - if callstack: - self.printer.writelines( - "finally:", - "context.caller_stack._pop_frame()", - None - ) - - if buffered or filtered or cached: - if buffered or cached: - # in a caching scenario, don't try to get a writer - # from the context after popping; assume the caching - # implemenation might be using a context with no - # extra buffers - self.printer.writelines( - "finally:", - "__M_buf = context._pop_buffer()" - ) - else: - self.printer.writelines( - "finally:", - "__M_buf, __M_writer = context._pop_buffer_and_writer()" - ) - - if callstack: - self.printer.writeline("context.caller_stack._pop_frame()") - - s = "__M_buf.getvalue()" - if filtered: - s = self.create_filter_callable(node.filter_args.args, s, False) - self.printer.writeline(None) - if buffered and not cached: - s = self.create_filter_callable(self.compiler.buffer_filters, s, False) - if buffered or cached: - self.printer.writeline("return %s" % s) - else: - self.printer.writelines( - "__M_writer(%s)" % s, - "return ''" - ) - - def write_cache_decorator(self, node_or_pagetag, name, args, buffered, identifiers, inline=False, toplevel=False): - """write a post-function decorator to replace a rendering callable with a cached version of itself.""" - self.printer.writeline("__M_%s = %s" % (name, name)) - cachekey = node_or_pagetag.parsed_attributes.get('cache_key', repr(name)) - cacheargs = {} - for arg in (('cache_type', 'type'), ('cache_dir', 'data_dir'), ('cache_timeout', 'expiretime'), ('cache_url', 'url')): - val = node_or_pagetag.parsed_attributes.get(arg[0], None) - if val is not None: - if arg[1] == 'expiretime': - cacheargs[arg[1]] = int(eval(val)) - else: - cacheargs[arg[1]] = val - else: - if self.compiler.pagetag is not None: - val = self.compiler.pagetag.parsed_attributes.get(arg[0], None) - if val is not None: - if arg[1] == 'expiretime': - cacheargs[arg[1]] == int(eval(val)) - else: - cacheargs[arg[1]] = val - - self.printer.writeline("def %s(%s):" % (name, ','.join(args))) - - # form "arg1, arg2, arg3=arg3, arg4=arg4", etc. - pass_args = [ '=' in a and "%s=%s" % ((a.split('=')[0],)*2) or a for a in args] - - self.write_variable_declares(identifiers, toplevel=toplevel, limit=node_or_pagetag.undeclared_identifiers()) - if buffered: - s = "context.get('local').get_cached(%s, defname=%r, %screatefunc=lambda:__M_%s(%s))" % (cachekey, name, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ','.join(pass_args)) - # apply buffer_filters - s = self.create_filter_callable(self.compiler.buffer_filters, s, False) - self.printer.writelines("return " + s,None) - else: - self.printer.writelines( - "__M_writer(context.get('local').get_cached(%s, defname=%r, %screatefunc=lambda:__M_%s(%s)))" % (cachekey, name, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ','.join(pass_args)), - "return ''", - None - ) - - def create_filter_callable(self, args, target, is_expression): - """write a filter-applying expression based on the filters present in the given - filter names, adjusting for the global 'default' filter aliases as needed.""" - def locate_encode(name): - if re.match(r'decode\..+', name): - return "filters." + name - else: - return filters.DEFAULT_ESCAPES.get(name, name) - - if 'n' not in args: - if is_expression: - if self.compiler.pagetag: - args = self.compiler.pagetag.filter_args.args + args - if self.compiler.default_filters: - args = self.compiler.default_filters + args - for e in args: - # if filter given as a function, get just the identifier portion - if e == 'n': - continue - m = re.match(r'(.+?)(\(.*\))', e) - if m: - (ident, fargs) = m.group(1,2) - f = locate_encode(ident) - e = f + fargs - else: - x = e - e = locate_encode(e) - assert e is not None - target = "%s(%s)" % (e, target) - return target - - def visitExpression(self, node): - self.write_source_comment(node) - if len(node.escapes) or (self.compiler.pagetag is not None and len(self.compiler.pagetag.filter_args.args)) or len(self.compiler.default_filters): - s = self.create_filter_callable(node.escapes_code.args, "%s" % node.text, True) - self.printer.writeline("__M_writer(%s)" % s) - else: - self.printer.writeline("__M_writer(%s)" % node.text) - - def visitControlLine(self, node): - if node.isend: - self.printer.writeline(None) - else: - self.write_source_comment(node) - self.printer.writeline(node.text) - def visitText(self, node): - self.write_source_comment(node) - self.printer.writeline("__M_writer(%s)" % repr(node.content)) - def visitTextTag(self, node): - filtered = len(node.filter_args.args) > 0 - if filtered: - self.printer.writelines( - "__M_writer = context._push_writer()", - "try:", - ) - for n in node.nodes: - n.accept_visitor(self) - if filtered: - self.printer.writelines( - "finally:", - "__M_buf, __M_writer = context._pop_buffer_and_writer()", - "__M_writer(%s)" % self.create_filter_callable(node.filter_args.args, "__M_buf.getvalue()", False), - None - ) - - def visitCode(self, node): - if not node.ismodule: - self.write_source_comment(node) - self.printer.write_indented_block(node.text) - - if not self.in_def and len(self.identifiers.locally_assigned) > 0: - # if we are the "template" def, fudge locally declared/modified variables into the "__M_locals" dictionary, - # which is used for def calls within the same template, to simulate "enclosing scope" - self.printer.writeline('__M_locals.update(__M_dict_builtin([(__M_key, __M_locals_builtin()[__M_key]) for __M_key in [%s] if __M_key in __M_locals_builtin()]))' % ','.join([repr(x) for x in node.declared_identifiers()])) - - def visitIncludeTag(self, node): - self.write_source_comment(node) - args = node.attributes.get('args') - if args: - self.printer.writeline("runtime._include_file(context, %s, _template_uri, %s)" % (node.parsed_attributes['file'], args)) - else: - self.printer.writeline("runtime._include_file(context, %s, _template_uri)" % (node.parsed_attributes['file'])) - - def visitNamespaceTag(self, node): - pass - - def visitDefTag(self, node): - pass - - def visitCallNamespaceTag(self, node): - # TODO: we can put namespace-specific checks here, such - # as ensure the given namespace will be imported, - # pre-import the namespace, etc. - self.visitCallTag(node) - - def visitCallTag(self, node): - self.printer.writeline("def ccall(caller):") - export = ['body'] - callable_identifiers = self.identifiers.branch(node, nested=True) - body_identifiers = callable_identifiers.branch(node, nested=False) - # we want the 'caller' passed to ccall to be used for the body() function, - # but for other non-body() <%def>s within <%call> we want the current caller off the call stack (if any) - body_identifiers.add_declared('caller') - - self.identifier_stack.append(body_identifiers) - class DefVisitor(object): - def visitDefTag(s, node): - self.write_inline_def(node, callable_identifiers, nested=False) - export.append(node.name) - # remove defs that are within the <%call> from the "closuredefs" defined - # in the body, so they dont render twice - if node.name in body_identifiers.closuredefs: - del body_identifiers.closuredefs[node.name] - - vis = DefVisitor() - for n in node.nodes: - n.accept_visitor(vis) - self.identifier_stack.pop() - - bodyargs = node.body_decl.get_argument_expressions() - self.printer.writeline("def body(%s):" % ','.join(bodyargs)) - # TODO: figure out best way to specify buffering/nonbuffering (at call time would be better) - buffered = False - if buffered: - self.printer.writelines( - "context._push_buffer()", - "try:" - ) - self.write_variable_declares(body_identifiers) - self.identifier_stack.append(body_identifiers) - - for n in node.nodes: - n.accept_visitor(self) - self.identifier_stack.pop() - - self.write_def_finish(node, buffered, False, False, callstack=False) - self.printer.writelines( - None, - "return [%s]" % (','.join(export)), - None - ) - - self.printer.writelines( - # get local reference to current caller, if any - "caller = context.caller_stack._get_caller()", - # push on caller for nested call - "context.caller_stack.nextcaller = runtime.Namespace('caller', context, callables=ccall(caller))", - "try:") - self.write_source_comment(node) - self.printer.writelines( - "__M_writer(%s)" % self.create_filter_callable([], node.expression, True), - "finally:", - "context.caller_stack.nextcaller = None", - None - ) - -class _Identifiers(object): - """tracks the status of identifier names as template code is rendered.""" - def __init__(self, node=None, parent=None, nested=False): - if parent is not None: - # things that have already been declared in an enclosing namespace (i.e. names we can just use) - self.declared = util.Set(parent.declared).union([c.name for c in parent.closuredefs.values()]).union(parent.locally_declared).union(parent.argument_declared) - - # if these identifiers correspond to a "nested" scope, it means whatever the - # parent identifiers had as undeclared will have been declared by that parent, - # and therefore we have them in our scope. - if nested: - self.declared = self.declared.union(parent.undeclared) - - # top level defs that are available - self.topleveldefs = util.SetLikeDict(**parent.topleveldefs) - else: - self.declared = util.Set() - self.topleveldefs = util.SetLikeDict() - - # things within this level that are referenced before they are declared (e.g. assigned to) - self.undeclared = util.Set() - - # things that are declared locally. some of these things could be in the "undeclared" - # list as well if they are referenced before declared - self.locally_declared = util.Set() - - # assignments made in explicit python blocks. these will be propigated to - # the context of local def calls. - self.locally_assigned = util.Set() - - # things that are declared in the argument signature of the def callable - self.argument_declared = util.Set() - - # closure defs that are defined in this level - self.closuredefs = util.SetLikeDict() - - self.node = node - - if node is not None: - node.accept_visitor(self) - - def branch(self, node, **kwargs): - """create a new Identifiers for a new Node, with this Identifiers as the parent.""" - return _Identifiers(node, self, **kwargs) - - defs = property(lambda self:util.Set(self.topleveldefs.union(self.closuredefs).values())) - - def __repr__(self): - return "Identifiers(declared=%s, locally_declared=%s, undeclared=%s, topleveldefs=%s, closuredefs=%s, argumenetdeclared=%s)" % (repr(list(self.declared)), repr(list(self.locally_declared)), repr(list(self.undeclared)), repr([c.name for c in self.topleveldefs.values()]), repr([c.name for c in self.closuredefs.values()]), repr(self.argument_declared)) - - def check_declared(self, node): - """update the state of this Identifiers with the undeclared and declared identifiers of the given node.""" - for ident in node.undeclared_identifiers(): - if ident != 'context' and ident not in self.declared.union(self.locally_declared): - self.undeclared.add(ident) - for ident in node.declared_identifiers(): - self.locally_declared.add(ident) - - def add_declared(self, ident): - self.declared.add(ident) - if ident in self.undeclared: - self.undeclared.remove(ident) - - def visitExpression(self, node): - self.check_declared(node) - def visitControlLine(self, node): - self.check_declared(node) - def visitCode(self, node): - if not node.ismodule: - self.check_declared(node) - self.locally_assigned = self.locally_assigned.union(node.declared_identifiers()) - def visitDefTag(self, node): - if node.is_root(): - self.topleveldefs[node.name] = node - elif node is not self.node: - self.closuredefs[node.name] = node - for ident in node.undeclared_identifiers(): - if ident != 'context' and ident not in self.declared.union(self.locally_declared): - self.undeclared.add(ident) - # visit defs only one level deep - if node is self.node: - for ident in node.declared_identifiers(): - self.argument_declared.add(ident) - for n in node.nodes: - n.accept_visitor(self) - def visitIncludeTag(self, node): - self.check_declared(node) - def visitPageTag(self, node): - for ident in node.declared_identifiers(): - self.argument_declared.add(ident) - self.check_declared(node) - - def visitCallNamespaceTag(self, node): - self.visitCallTag(node) - - def visitCallTag(self, node): - if node is self.node: - for ident in node.undeclared_identifiers(): - if ident != 'context' and ident not in self.declared.union(self.locally_declared): - self.undeclared.add(ident) - for ident in node.declared_identifiers(): - self.argument_declared.add(ident) - for n in node.nodes: - n.accept_visitor(self) - else: - for ident in node.undeclared_identifiers(): - if ident != 'context' and ident not in self.declared.union(self.locally_declared): - self.undeclared.add(ident) - |
