def splitdocfor(path):
    """split the docstring for a path
    
    valid paths are::
        
        ./path/to/module.py
        ./path/to/module.py:SomeClass.method
    
    returns (description, long_description) from the docstring for path 
    or (None, None) if there isn't a docstring.
    
    Example::
    
        >>> splitdocfor("./wsgi_intercept/__init__.py")[0]
        'installs a WSGI application in place of a real URI for testing.'
        >>> splitdocfor("./wsgi_intercept/__init__.py:WSGI_HTTPConnection.get_app")[0]
        'Return the app object for the given (host, port).'
        >>> 
        
    """
    if ":" in path:
        filename, objpath = path.split(':')
    else:
        filename, objpath = path, None
    inspector = DocInspector(filename)
    visitor.walk(compiler.parseFile(filename), inspector)
    if objpath is None:
        if inspector.top_level_doc is None:
            return None, None
        return pydoc.splitdoc(inspector.top_level_doc)
    else:
        if inspector[objpath] is None:
            return None, None
        return pydoc.splitdoc(inspector[objpath])
Esempio n. 2
0
def parse(buf, mode="exec"):
    context = CompilerContext()
    parser = Parser.FromString(sys, context, buf)
    node = parser.ParseFileInput()
    tree = Transformer().parsefile(node)
    walk(tree, FlattenVisitor())
    return tree
Esempio n. 3
0
def parse(buf, mode='exec'):
    context = CompilerContext()
    parser = Parser.FromString(sys, context, buf)
    node = parser.ParseFileInput()
    tree = Transformer().parsefile(node)
    walk(tree, FlattenVisitor())
    return tree
Esempio n. 4
0
def splitdocfor(path):
    """split the docstring for a path
    
    valid paths are::
        
        ./path/to/module.py
        ./path/to/module.py:SomeClass.method
    
    returns (description, long_description) from the docstring for path 
    or (None, None) if there isn't a docstring.
    
    Example::
    
        >>> splitdocfor("./wsgi_intercept/__init__.py")[0]
        'installs a WSGI application in place of a real URI for testing.'
        >>> splitdocfor("./wsgi_intercept/__init__.py:WSGI_HTTPConnection.get_app")[0]
        'Return the app object for the given (host, port).'
        >>> 
        
    """
    if ":" in path:
        filename, objpath = path.split(':')
    else:
        filename, objpath = path, None
    inspector = DocInspector(filename)
    visitor.walk(compiler.parseFile(filename), inspector)
    if objpath is None:
        if inspector.top_level_doc is None:
            return None, None
        return pydoc.splitdoc(inspector.top_level_doc)
    else:
        if inspector[objpath] is None:
            return None, None
        return pydoc.splitdoc(inspector[objpath])
Esempio n. 5
0
    def visitCode(self, node):
        gen = self.BlockGen(node, self.scopes, self.get_module(), node.lazy)
        visitor.walk(node.code, gen)
        gen.finish()
        self.set_lineno(node)

        #self.emit('LOAD_CONST', node.name)

        frees = gen.scope.get_free_vars()
        #print node.name, 'free', frees
        gen.scope.DEBUG()
        self.makeClosure(gen, 0, frees)

        self.emit('LOAD_CONST', gen)
        
        if not node.lazy:
            if frees:
                self.emit('MAKE_CLOSURE', 0)
            else:
                self.emit('MAKE_FUNCTION', 0)
            #self.emit('CALL_FUNCTION', 0)

        self.storeName(node.name)

        if node.wrapper is not None:
            # load wrapper callable to TOS
            self.visit(node.wrapper)
            # load pattern name to TOS
            self.emit('LOAD_CONST', node.name)
            # load pattern to TOS
            self.loadName(node.name)
            # call wrapper(name, pattern)
            self.emit('CALL_FUNCTION', 2)
            # store it back
            self.storeName(node.name)
Esempio n. 6
0
    def __init__(self, code, **exception_kwargs):
        self.codeargs = []
        self.args = []
        self.declared_identifiers = util.Set()
        self.undeclared_identifiers = util.Set()

        class FindTuple(object):
            def visitTuple(s, node, *args):
                for n in node.nodes:
                    p = PythonCode(n, **exception_kwargs)
                    self.codeargs.append(p)
                    self.args.append(ExpressionGenerator(n).value())
                    self.declared_identifiers = self.declared_identifiers.union(p.declared_identifiers)
                    self.undeclared_identifiers = self.undeclared_identifiers.union(p.undeclared_identifiers)

        if isinstance(code, basestring):
            if re.match(r"\S", code) and not re.match(r",\s*$", code):
                # if theres text and no trailing comma, insure its parsed
                # as a tuple by adding a trailing comma
                code += ","
            expr = parse(code, "exec", **exception_kwargs)
        else:
            expr = code

        f = FindTuple()
        visitor.walk(expr, f)
Esempio n. 7
0
    def __init__(self, code, **exception_kwargs):
        self.codeargs = []
        self.args = []
        self.declared_identifiers = util.Set()
        self.undeclared_identifiers = util.Set()

        class FindTuple(object):
            def visitTuple(s, node, *args):
                for n in node.nodes:
                    p = PythonCode(n, **exception_kwargs)
                    self.codeargs.append(p)
                    self.args.append(ExpressionGenerator(n).value())
                    self.declared_identifiers = self.declared_identifiers.union(
                        p.declared_identifiers)
                    self.undeclared_identifiers = self.undeclared_identifiers.union(
                        p.undeclared_identifiers)

        if isinstance(code, basestring):
            if re.match(r"\S", code) and not re.match(r",\s*$", code):
                # if theres text and no trailing comma, insure its parsed
                # as a tuple by adding a trailing comma
                code += ","
            expr = parse(code, "exec", **exception_kwargs)
        else:
            expr = code

        f = FindTuple()
        visitor.walk(expr, f)
Esempio n. 8
0
    def visitCode(self, node):
        gen = self.BlockGen(node, self.scopes, self.get_module(), node.lazy)
        visitor.walk(node.code, gen)
        gen.finish()
        self.set_lineno(node)

        #self.emit('LOAD_CONST', node.name)

        frees = gen.scope.get_free_vars()
        #print node.name, 'free', frees
        gen.scope.DEBUG()
        self.makeClosure(gen, 0, frees)

        self.emit('LOAD_CONST', gen)

        if not node.lazy:
            if frees:
                self.emit('MAKE_CLOSURE', 0)
            else:
                self.emit('MAKE_FUNCTION', 0)
            #self.emit('CALL_FUNCTION', 0)

        self.storeName(node.name)

        if node.wrapper is not None:
            # load wrapper callable to TOS
            self.visit(node.wrapper)
            # load pattern name to TOS
            self.emit('LOAD_CONST', node.name)
            # load pattern to TOS
            self.loadName(node.name)
            # call wrapper(name, pattern)
            self.emit('CALL_FUNCTION', 2)
            # store it back
            self.storeName(node.name)
Esempio n. 9
0
def processModuleAst(ast, name, system):
    mv = system.ModuleVistor(system, name)
    walk(ast, mv)
    while mv.morenodes:
        obj, node = mv.morenodes.pop(0)
        system.push(obj, node)
        mv.visit(node)
        system.pop(obj)
Esempio n. 10
0
def processModuleAst(ast, name, system):
    mv = system.ModuleVistor(system, name)
    walk(ast, mv)
    while mv.morenodes:
        obj, node = mv.morenodes.pop(0)
        system.push(obj, node)
        mv.visit(node)
        system.pop(obj)
Esempio n. 11
0
 def _visitOp(self, node, fn):
     """Traverse binary operators like '+', '-', '/', etc.
     fn - function which abstract representation of particular operation.
     """
     (left, right) = node.getChildren()
     visitor = FunctionVisitor()
     walk(left, visitor, visitor)
     walk(right, visitor, visitor)
     self.children.append(fn(*visitor.children))
Esempio n. 12
0
def get_module_meta(modfile):
    ast = compiler.parseFile(modfile)
    modnode = ModuleVisitor()
    visitor.walk(ast, modnode)
    if modnode.mod_doc is None:
        raise RuntimeError("could not parse doc string from %s" % modfile)
    if modnode.mod_version is None:
        raise RuntimeError("could not parse __version__ from %s" % modfile)
    return (modnode.mod_version, ) + pydoc.splitdoc(modnode.mod_doc)
Esempio n. 13
0
File: setup.py Progetto: lqc/fixture
def get_module_meta(modfile):            
    ast = compiler.parseFile(modfile)
    modnode = ModuleVisitor()
    visitor.walk(ast, modnode)
    if modnode.mod_doc is None:
        raise RuntimeError(
            "could not parse doc string from %s" % modfile)
    if modnode.mod_version is None:
        raise RuntimeError(
            "could not parse __version__ from %s" % modfile)
    return (modnode.mod_version,) + pydoc.splitdoc(modnode.mod_doc)
Esempio n. 14
0
def normalize_file(filename, *args):
    """ Import-normalize a file.

    If the file is not parseable, an empty filelike object will be returned.
    """
    try:
        ast = compiler.parseFile(filename)
    except Exception as e:
        return StringIO('')
    ip = ImportPuller()
    walk(ast, ip)
    return StringIO(ip.as_string())
Esempio n. 15
0
def findImportStars(system):
    assert system.state in ['preparse']
    modlist = list(system.objectsOfType(Module))
    for mod in modlist:
        system.push(mod.parent)
        isf = ImportStarFinder(system, mod.fullName())
        try:
            ast = parseFile(mod.filepath)
        except (SyntaxError, ValueError):
            system.warning("cannot parse", mod.filepath)
        walk(ast, isf)
        system.pop(mod.parent)
    system.state = 'importstarred'
Esempio n. 16
0
def findImportStars(system):
    assert system.state in ['preparse']
    modlist = list(system.objectsOfType(Module))
    for mod in modlist:
        system.push(mod.parent)
        isf = ImportStarFinder(system, mod.fullName())
        try:
            ast = parseFile(mod.filepath)
        except (SyntaxError, ValueError):
            system.warning("cannot parse", mod.filepath)
        walk(ast, isf)
        system.pop(mod.parent)
    system.state = 'importstarred'
Esempio n. 17
0
 def visitFunction(self, node):
     """Create export attribute and start traverse
     function body (depth-first search)"""
     # (decorators, name, argnames, defaults, flags, docs, code)
     cn = node.getChildren()
     fn_name = cn[1]
     argnames = cn[2]
     code = cn[-1]
     visitor = FunctionVisitor()
     walk(code, visitor, visitor)
     self.functions.append(erl.function_af(fn_name, argnames,
                                             visitor.children))
     self.exports.append(erl.export_af(fn_name, argnames))
Esempio n. 18
0
 def visitPrintnl(self, node):
     """Print to io:format.
     Print has several forms:
         print 'test'
         print 'test', var
         print 'test %s' % var
         print 'test {0}'.format(var)
     """
     # node children format: ([node1, node2, ...,] dist)
     nodes = node.getChildren()
     nodes = nodes[0]
     visitor = FunctionVisitor()
     for n in nodes:
         walk(nodes, visitor, visitor)
     visitor.children.append(erl.nil_af())
     self.children.append(erl.io_format_af(visitor.children))
Esempio n. 19
0
 def __init__(self, code, allow_kwargs=True, **exception_kwargs):
     self.code = code
     expr = parse(code, "exec", **exception_kwargs)
     class ParseFunc(object):
         def visitFunction(s, node, *args):
             self.funcname = node.name
             self.argnames = node.argnames
             self.defaults = node.defaults
             self.varargs = node.varargs
             self.kwargs = node.kwargs
             
     f = ParseFunc()
     visitor.walk(expr, f)
     if not hasattr(self, 'funcname'):
         raise exceptions.CompileException("Code '%s' is not a function declaration" % code, **exception_kwargs)
     if not allow_kwargs and self.kwargs:
         raise exceptions.CompileException("'**%s' keyword argument not allowed here" % self.argnames[-1], **exception_kwargs)
Esempio n. 20
0
 def __init__(self, block, scopes, module):
     self.block_name = block.name
     self.module = module
     self.graph = pyassem.PyFlowGraph(block.name, block.filename,
                                        optimized=0)
     self.super_init()
     lnf = visitor.walk(block.code, self.NameFinder(), verbose=0)
     self.locals.push(lnf.getLocals())
     if not self.lazy:
         self.graph.setFlag(CO_NEWLOCALS)
     if block.doc:
         self.setDocstring(block.doc)
Esempio n. 21
0
 def __init__(self, block, scopes, module):
     self.block_name = block.name
     self.module = module
     self.graph = pyassem.PyFlowGraph(block.name,
                                      block.filename,
                                      optimized=0)
     self.super_init()
     lnf = visitor.walk(block.code, self.NameFinder(), verbose=0)
     self.locals.push(lnf.getLocals())
     if not self.lazy:
         self.graph.setFlag(CO_NEWLOCALS)
     if block.doc:
         self.setDocstring(block.doc)
Esempio n. 22
0
    def __init__(self, code, allow_kwargs=True, **exception_kwargs):
        self.code = code
        expr = parse(code, "exec", **exception_kwargs)

        class ParseFunc(object):
            def visitFunction(s, node, *args):
                self.funcname = node.name
                self.argnames = node.argnames
                self.defaults = node.defaults
                self.varargs = node.varargs
                self.kwargs = node.kwargs

        f = ParseFunc()
        visitor.walk(expr, f)
        if not hasattr(self, 'funcname'):
            raise exceptions.CompileException(
                "Code '%s' is not a function declaration" % code,
                **exception_kwargs)
        if not allow_kwargs and self.kwargs:
            raise exceptions.CompileException(
                "'**%s' keyword argument not allowed here" % self.argnames[-1],
                **exception_kwargs)
Esempio n. 23
0
 def parseSymbols(self, tree):
     s = ptpysymbols.PtpySymbolVisitor()
     visitor.walk(tree, s)
     return s.scopes
Esempio n. 24
0
 def parseSymbols(self, tree):
     s = lucysymbols.LucySymbolVisitor()
     visitor.walk(tree, s)
     return s.scopes
Esempio n. 25
0
 def __init__(self, tree):
     self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
     self.futures = future.find_futures(tree)
     self.__super_init()
     visitor.walk(tree, self)
Esempio n. 26
0
    return os.path.basename(os.path.splitext(file_name)[0])

COMPILER = 'compile_forms'

if __name__ == '__main__':

    if len(sys.argv) == 2:
        fname = sys.argv[1]
        erl_out = None
        try:
            module_tree = compiler.parseFile(fname)
            if isinstance(module_tree, compiler.ast.Module):
                doc, module_body = module_tree.getChildren()

                visitor = ModuleVisitor()
                walk(module_body, visitor, visitor)
                forms = erl.full_af(erl.module_af(module_name(fname)),
                                    visitor.exports, visitor.functions)

                retcode = subprocess.call(['erlc',
                    'py2erl/erl/{compiler}.erl'.format(compiler=COMPILER)])
                if not retcode:
                    retcode = subprocess.call(['erl', '-noshell', '-eval',
                        "code:load_file('{compiler}'),"\
                        "{compiler}:compile({forms}),"\
                        "erlang:halt()".format(forms=forms, compiler=COMPILER)])
                    if not retcode:
                        logging.info('Successfully compiled')
                    else:
                        logging.error('Can not compile abstract forms')
                else:
Esempio n. 27
0
 def parseSymbols(self, tree):
     s = lucysymbols.LucySymbolVisitor()
     visitor.walk(tree, s)
     return s.scopes
Esempio n. 28
0
    def __init__(self, code, **exception_kwargs):
        self.code = code

        # represents all identifiers which are assigned to at some point in the code
        self.declared_identifiers = util.Set()

        # represents all identifiers which are referenced before their assignment, if any
        self.undeclared_identifiers = util.Set()

        # note that an identifier can be in both the undeclared and declared lists.

        # using AST to parse instead of using code.co_varnames, code.co_names has several advantages:
        # - we can locate an identifier as "undeclared" even if its declared later in the same block of code
        # - AST is less likely to break with version changes (for example, the behavior of co_names changed a little bit
        # in python version 2.5)
        if isinstance(code, basestring):
            expr = parse(code.lstrip(), "exec", **exception_kwargs)
        else:
            expr = code

        class FindIdentifiers(object):
            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 visitClass(self, node, *args):
                self._add_declared(node.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)
                self.visit(node.expr, *args)
                for n in node.nodes:
                    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 self.local_ident_stack:
                        saved[arg] = True
                    else:
                        self.local_ident_stack[arg] = True
                for n in node.getChildNodes():
                    self.visit(n, *args)
                self.in_function = inf
                for arg in node.argnames:
                    if arg not in saved:
                        del self.local_ident_stack[arg]

            def visitFor(self, node, *args):
                # flip around visit
                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 s.local_ident_stack:
                    self.undeclared_identifiers.add(node.name)

            def visitImport(self, node, *args):
                for (mod, alias) in node.names:
                    if alias is not None:
                        self._add_declared(alias)
                    else:
                        self._add_declared(mod.split('.')[0])

            def visitFrom(self, node, *args):
                for (mod, alias) in node.names:
                    if alias is not None:
                        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.",
                                **exception_kwargs)
                        self._add_declared(mod)

        f = FindIdentifiers()
        visitor.walk(expr, f)  #, walker=walker())
Esempio n. 29
0
        """ Concatenate all of the 'import' and 'from' statements.
        """
        return ''.join(self.statements)


def normalize_file(filename, *args):
    """ Import-normalize a file.

    If the file is not parseable, an empty filelike object will be returned.
    """
    try:
        ast = compiler.parseFile(filename)
    except Exception, e:
        return StringIO('')
    ip = ImportPuller()
    walk(ast, ip)
    return StringIO(ip.as_string())


def get_grinimports_arg_parser(parser=None):
    """ Create the command-line parser.
    """
    parser = grin.get_grin_arg_parser(parser)
    parser.set_defaults(include='*.py')
    parser.description = ("Extract, normalize and search import statements "
                          "from Python files.")
    parser.epilog = """
For example, if I have a file example.py with a bunch of imports:

    $ cat example.py
    import foo
Esempio n. 30
0
 def __init__(self, astnode):
     self.buf = StringIO()
     visitor.walk(astnode, self) #, walker=walker())
Esempio n. 31
0
 def visit(self, expr):
     visitor.walk(expr, self)
Esempio n. 32
0
 def __init__(self, tree):
     self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
     self.futures = future.find_futures(tree)
     self.__super_init()
     visitor.walk(tree, self)
Esempio n. 33
0
 def visit(self, expr):
     visitor.walk(expr, self)
Esempio n. 34
0
 def processModuleAST(self, ast, mod):
     findAll(ast, mod)
     visitor.walk(ast, self.ModuleVistor(self, mod))
Esempio n. 35
0
def ast2hir(ast):
    v = HIRASTVisitor()
    visitor.walk(ast, v)
    return v.top()
Esempio n. 36
0
"""Package for compiling Python source code

There are several functions defined at the top level that are imported
from modules contained in the package.

walk(ast, visitor, verbose=None)
    Does a pre-order walk over the ast using the visitor instance.
    See compiler.visitor for details.

compile(source, filename, mode, flags=None, dont_inherit=None)
    Returns a code object.  A replacement for the builtin compile() function.

compileFile(filename)
    Generates a .pyc file by compiling filename.
"""

from compiler.visitor import walk
from compiler.pycodegen import compile, compileFile
Esempio n. 37
0
def testSymbolVisitor():

    def PrintScopes(scopes):
        result = []
        for i in sorted(scopes, key=lambda x:x.name):
            result.append('- %s' % i)
            for j in sorted(i.uses):
                result.append('  - %s' % j)
        return '\n'.join(result)

    source_code = Dedent(
        '''
        from alpha import Alpha
        import coilib50

        class Zulu(Alpha):
            """
            Zulu class docs.
            """

            def __init__(self, name):
                """
                Zulu.__init__ docs.
                """
                self._name = name
                alpha = bravo
                coilib50.Charlie()
                f = coilib50.Delta(echo, foxtrot)
        '''
    )

    from terraformer._visitor import ASTVisitor
    code = TerraFormer._Parse(source_code)
    visitor = ASTVisitor()
    visitor.Visit(code)

    assert visitor._module.AsString() == Dedent(
        '''
            module (1, 0) module
              IMPORT-BLOCK (1, 0) import-block #0
                IMPORT-FROM (0, 0) alpha
                  IMPORT (1, 0) alpha.Alpha
                IMPORT (2, 0) coilib50
              USE (3, 0) Alpha
              class (0, 0) Zulu
                def (8, 4) __init__
                  ARG (9, 17) self
                  ARG (9, 23) name
                  DEF (13, 8) self._name
                  USE (13, 21) name
                  DEF (14, 8) alpha
                  USE (14, 16) bravo
                  USE (15, 8) coilib50.Charlie
                  DEF (16, 8) f
                  USE (16, 12) coilib50.Delta
                  USE (16, 27) echo
                  USE (16, 33) foxtrot
        '''
    )

    # Compares the results with the one given by compiler.symbols.SymbolVisitor, our inspiration.
    from compiler.symbols import SymbolVisitor
    from compiler.transformer import parse
    from compiler.visitor import walk

    code = parse(source_code)
    symbol_visitor = SymbolVisitor()
    walk(code, symbol_visitor)

    assert PrintScopes(symbol_visitor.scopes.values()) == Dedent(
        '''
            - <ClassScope: Zulu>
            - <FunctionScope: __init__>
              - bravo
              - coilib50
              - echo
              - foxtrot
              - name
              - self
            - <ModuleScope: global>
              - Alpha
          '''
    )
Esempio n. 38
0
        """ Concatenate all of the 'import' and 'from' statements.
        """
        return ''.join(self.statements)


def normalize_file(filename, *args):
    """ Import-normalize a file.

    If the file is not parseable, an empty filelike object will be returned.
    """
    try:
        ast = compiler.parseFile(filename)
    except Exception, e:
        return StringIO('')
    ip = ImportPuller()
    walk(ast, ip)
    return StringIO(ip.as_string())

def get_grinimports_arg_parser(parser=None):
    """ Create the command-line parser.
    """
    parser = grin.get_grin_arg_parser(parser)
    parser.set_defaults(include='*.py')
    parser.description = ("Extract, normalize and search import statements "
        "from Python files.")
    parser.epilog = """
For example, if I have a file example.py with a bunch of imports:

    $ cat example.py
    import foo
    import foo.baz as blah
Esempio n. 39
0
 def visitReturn(self, node):
     """Continue traversing in depth"""
     (value,) = node.getChildren()
     walk(value, self, self)
Esempio n. 40
0
 def processModuleAST(self, ast, mod):
     findAll(ast, mod)
     visitor.walk(ast, self.ModuleVistor(self, mod))
Esempio n. 41
0
 def visitStmt(self, node):
     """Continue traversing in depth"""
     for n in node.getChildren():
         walk(n, self, self)
Esempio n. 42
0
    def __init__(self, code, **exception_kwargs):
        self.code = code
        
        # represents all identifiers which are assigned to at some point in the code
        self.declared_identifiers = util.Set()
        
        # represents all identifiers which are referenced before their assignment, if any
        self.undeclared_identifiers = util.Set()
        
        # note that an identifier can be in both the undeclared and declared lists.

        # using AST to parse instead of using code.co_varnames, code.co_names has several advantages:
        # - we can locate an identifier as "undeclared" even if its declared later in the same block of code
        # - AST is less likely to break with version changes (for example, the behavior of co_names changed a little bit
        # in python version 2.5)
        if isinstance(code, basestring):
            expr = parse(code.lstrip(), "exec", **exception_kwargs)
        else:
            expr = code
        
        class FindIdentifiers(object):
            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 visitClass(self, node, *args):
                self._add_declared(node.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)
                self.visit(node.expr, *args)
                for n in node.nodes:
                    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 self.local_ident_stack:
                        saved[arg] = True
                    else:
                        self.local_ident_stack[arg] = True
                for n in node.getChildNodes():
                    self.visit(n, *args)
                self.in_function = inf
                for arg in node.argnames:
                    if arg not in saved:
                        del self.local_ident_stack[arg]
            def visitFor(self, node, *args):
                # flip around visit
                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 s.local_ident_stack:
                    self.undeclared_identifiers.add(node.name)
            def visitImport(self, node, *args):
                for (mod, alias) in node.names:
                    if alias is not None:
                        self._add_declared(alias)
                    else:
                        self._add_declared(mod.split('.')[0])
            def visitFrom(self, node, *args):
                for (mod, alias) in node.names:
                    if alias is not None:
                        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.", **exception_kwargs)
                        self._add_declared(mod)
        f = FindIdentifiers()
        visitor.walk(expr, f) #, walker=walker())
Esempio n. 43
0
 def visit(self, expr):
     visitor.walk(expr, self)  # , walker=walker())
Esempio n. 44
0
 def visit(self, expr):
     visitor.walk(expr, self) #, walker=walker())
Esempio n. 45
0
 def __init__(self, astnode):
     self.buf = StringIO()
     visitor.walk(astnode, self)  # , walker=walker())
Esempio n. 46
0
def testSymbolVisitor():

    def PrintScopes(scopes):
        result = []
        for i in sorted(scopes, key=lambda x:x.name):
            result.append('- %s' % i)
            for j in sorted(i.uses):
                result.append('  - %s' % j)
        return '\n'.join(result)

    source_code = dedent(
        '''
        from alpha import Alpha
        import coilib50

        class Zulu(Alpha):
            """
            Zulu class docs.
            """

            def __init__(self, name):
                """
                Zulu.__init__ docs.
                """
                self._name = name
                alpha = bravo
                coilib50.Charlie()
                f = coilib50.Delta(echo, foxtrot)
        '''
    )

    from zerotk.terraformer._visitor import ASTVisitor
    code = TerraFormer._Parse(source_code)
    visitor = ASTVisitor()
    visitor.Visit(code)

    assert visitor._module.AsString() == dedent(
        '''
            module (1, 0) module
              IMPORT-BLOCK (1, 0) import-block #0
                IMPORT-FROM (0, 0) alpha
                  IMPORT (1, 0) alpha.Alpha
                IMPORT (2, 0) coilib50
              USE (3, 0) Alpha
              class (0, 0) Zulu
                def (8, 4) __init__
                  ARG (9, 17) self
                  ARG (9, 23) name
                  DEF (13, 8) self._name
                  USE (13, 21) name
                  DEF (14, 8) alpha
                  USE (14, 16) bravo
                  USE (15, 8) coilib50.Charlie
                  DEF (16, 8) f
                  USE (16, 12) coilib50.Delta
                  USE (16, 27) echo
                  USE (16, 33) foxtrot
        '''
    )

    # Compares the results with the one given by compiler.symbols.SymbolVisitor, our inspiration.
    from compiler.symbols import SymbolVisitor
    from compiler.transformer import parse
    from compiler.visitor import walk

    code = parse(source_code)
    symbol_visitor = SymbolVisitor()
    walk(code, symbol_visitor)

    assert PrintScopes(symbol_visitor.scopes.values()) == dedent(
        '''
            - <ClassScope: Zulu>
            - <FunctionScope: __init__>
              - bravo
              - coilib50
              - echo
              - foxtrot
              - name
              - self
            - <ModuleScope: global>
              - Alpha
          '''
    )