summaryrefslogtreecommitdiffstats
path: root/contrib/python/pythran/pythran/analyses/local_declarations.py
blob: 9a538911866135b4f51cec2b06bbb69eb4b004a2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
"""
LocalNameDeclarations gathers name of declarations local to a node.
LocalNodeDeclarations gathers node of declarations local to a node.
"""

from pythran.passmanager import NodeAnalysis

import gast as ast


class LocalNodeDeclarations(NodeAnalysis):

    """
    Gathers all local symbols from a function.

    It should not be use from outside a function, but can be used on a function
    (but in that case, parameters are not taken into account)

    >>> import gast as ast
    >>> from pythran import passmanager, backend
    >>> node = ast.parse('''
    ... def foo(a):
    ...     b = a + 1''')
    >>> pm = passmanager.PassManager("test")
    >>> [name.id for name in pm.gather(LocalNodeDeclarations, node)]
    ['b']
    >>> node = ast.parse('''
    ... for c in range(n):
    ...     b = a + 1''')
    >>> pm = passmanager.PassManager("test")
    >>> sorted([name.id for name in pm.gather(LocalNodeDeclarations, node)])
    ['b', 'c']
    """

    ResultType = set

    def visit_Name(self, node):
        """ Any node with Store context is a new declaration. """
        if isinstance(node.ctx, ast.Store):
            self.result.add(node)


class LocalNameDeclarations(NodeAnalysis):

    """
    Gathers all local identifiers from a node.

    >>> import gast as ast
    >>> from pythran import passmanager, backend
    >>> node = ast.parse('''
    ... def foo(a):
    ...     b = a + 1''')
    >>> pm = passmanager.PassManager("test")
    >>> sorted(pm.gather(LocalNameDeclarations, node))
    ['a', 'b', 'foo']
    """

    """ Initialize empty set as the result. """
    ResultType = set

    def visit_Name(self, node):
        """ Any node with Store or Param context is a new identifier. """
        if isinstance(node.ctx, (ast.Store, ast.Param)):
            self.result.add(node.id)

    def visit_FunctionDef(self, node):
        """ Function name is a possible identifier. """
        self.result.add(node.name)
        self.generic_visit(node)